diff --git a/plugins/twitter.py b/plugins/twitter.py index 1e605c7..7ea0093 100644 --- a/plugins/twitter.py +++ b/plugins/twitter.py @@ -134,4 +134,3 @@ def twitter(inp): screen_name = tweet.find(screen_name).text return "%s %s: %s" % (time, screen_name, text) - diff --git a/plugins_available/babel.py b/plugins_available/babel.py deleted file mode 100644 index f12c3a6..0000000 --- a/plugins_available/babel.py +++ /dev/null @@ -1,93 +0,0 @@ -import urllib -import htmlentitydefs -import re -import json - -from util import hook - -########### from http://effbot.org/zone/re-sub.htm#unescape-html ############# - -def unescape(text): - - def fixup(m): - text = m.group(0) - if text[:2] == "&#": - # character reference - try: - if text[:3] == "&#x": - return unichr(int(text[3:-1], 16)) - else: - return unichr(int(text[2:-1])) - except ValueError: - pass - else: - # named entity - try: - text = unichr(htmlentitydefs.name2codepoint[text[1:-1]]) - except KeyError: - pass - return text # leave as is - - return re.sub("&#?\w+;", fixup, text) - -############################################################################## - -languages = 'ja fr de ko ru zh'.split() -language_pairs = zip(languages[:-1], languages[1:]) - - -def goog_trans(text, slang, tlang): - req_url = 'http://ajax.googleapis.com/ajax/services/language/translate' \ - '?v=1.0&q=%s&langpair=%s' - url = req_url % (urllib.quote(text, safe=''), slang + '%7C' + tlang) - page = urllib.urlopen(url).read() - parsed = json.loads(page) - if not 200 <= parsed['responseStatus'] < 300: - raise IOError('error with the translation server: %d: %s' % ( - parsed['responseStatus'], '')) - return unescape(parsed['responseData']['translatedText']) - - -def babel_gen(inp): - for language in languages: - inp = inp.encode('utf8') - trans = goog_trans(inp, 'en', language).encode('utf8') - inp = goog_trans(trans, language, 'en') - yield language, trans, inp - - -@hook.command -def babel(inp): - ".babel -- translates through multiple languages" - - if not inp: - return babel.__doc__ - - try: - return list(babel_gen(inp))[-1][2] - except IOError, e: - return e - - -@hook.command -def babelext(inp): - ".babelext -- like .babel, but with more detailed output" - - if not inp: - return babelext.__doc__ - - try: - babels = list(babel_gen(inp)) - except IOError, e: - return e - - out = u'' - for lang, trans, text in babels: - out += '%s:"%s", ' % (lang, text.decode('utf8')) - - out += 'en:"' + babels[-1][2].decode('utf8') + '"' - - if len(out) > 300: - out = out[:150] + ' ... ' + out[-150:] - - return out diff --git a/plugins_available/bf.py b/plugins_available/bf.py deleted file mode 100644 index 610fc19..0000000 --- a/plugins_available/bf.py +++ /dev/null @@ -1,87 +0,0 @@ -'''brainfuck interpreter adapted from (public domain) code at -http://brainfuck.sourceforge.net/brain.py''' - -import re -import random - -from util import hook - - -BUFFER_SIZE = 5000 -MAX_STEPS = 1000000 - - -@hook.command -def bf(inp): - ".bf -- executes brainfuck program """ - - if not inp: - return bf.__doc__ - - program = re.sub('[^][<>+-.,]', '', inp) - - # create a dict of brackets pairs, for speed later on - brackets={} - open_brackets=[] - for pos in range(len(program)): - if program[pos] == '[': - open_brackets.append(pos) - elif program[pos] == ']': - if len(open_brackets) > 0: - brackets[pos] = open_brackets[-1] - brackets[open_brackets[-1]] = pos - open_brackets.pop() - else: - return 'unbalanced brackets' - if len(open_brackets) != 0: - return 'unbalanced brackets' - - # now we can start interpreting - ip = 0 # instruction pointer - mp = 0 # memory pointer - steps = 0 - memory = [0] * BUFFER_SIZE #initial memory area - rightmost = 0 - output = "" #we'll save the output here - - # the main program loop: - while ip < len(program): - c = program[ip] - if c == '+': - memory[mp] = memory[mp] + 1 % 256 - elif c == '-': - memory[mp] = memory[mp] - 1 % 256 - elif c == '>': - mp += 1 - if mp > rightmost: - rightmost = mp - if mp >= len(memory): - # no restriction on memory growth! - memory.extend([0]*BUFFER_SIZE) - elif c == '<': - mp = mp - 1 % len(memory) - elif c == '.': - output += chr(memory[mp]) - if len(output) > 500: - break - elif c == ',': - memory[mp] = random.randint(1, 255) - elif c == '[': - if memory[mp] == 0: - ip = brackets[ip] - elif c == ']': - if memory[mp] != 0: - ip = brackets[ip] - - ip += 1 - steps += 1 - if steps > MAX_STEPS: - output += "Maximum number of steps exceeded" - break - - output = '/'.join(output.splitlines()) - - if output == '': - return 'no output' - - return unicode(output, 'iso-8859-1')[:430] diff --git a/plugins_available/bible.py b/plugins_available/bible.py deleted file mode 100644 index bc41a30..0000000 --- a/plugins_available/bible.py +++ /dev/null @@ -1,27 +0,0 @@ -import urllib - -from util import hook - - -@hook.command('god') -@hook.command -def bible(inp): - ".bible -- gets from the Bible (ESV)" - - if not inp: - return bible.__doc__ - - base_url = 'http://www.esvapi.org/v2/rest/passageQuery?key=IP&' \ - 'output-format=plain-text&include-heading-horizontal-lines&' \ - 'include-headings=false&include-passage-horizontal-lines=false&' \ - 'include-passage-references=false&include-short-copyright=false&' \ - 'include-footnotes=false&line-length=0&passage=' - - text = urllib.urlopen(base_url + urllib.quote(inp)).read() - - text = ' '.join(text.split()) - - if len(text) > 400: - text = text[:text.rfind(' ', 0, 400)] + '...' - - return text diff --git a/plugins_available/choose.py b/plugins_available/choose.py deleted file mode 100644 index 3c6788e..0000000 --- a/plugins_available/choose.py +++ /dev/null @@ -1,19 +0,0 @@ -import re -import random - -from util import hook - -@hook.command -def choose(inp): - ".choose , , ... -- makes a decision" - - if not inp: - return choose.__doc__ - - c = re.findall(r'([^,]+)', inp) - if len(c) == 1: - c = re.findall(r'(\S+)', inp) - if len(c) == 1: - return 'the decision is up to you' - - return random.choice(c).strip() diff --git a/plugins_available/dice.py b/plugins_available/dice.py deleted file mode 100644 index 13bb040..0000000 --- a/plugins_available/dice.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -dice.py: written by Scaevolus 2008, updated 2009 -simulates dicerolls -""" -import re -import random - -from util import hook - - -whitespace_re = re.compile(r'\s+') -valid_diceroll_re = re.compile(r'^[+-]?(\d+|\d*d\d+)([+-](\d+|\d*d\d+))*$') -sign_re = re.compile(r'[+-]?(?:\d*d)?\d+') -split_re = re.compile(r'([\d+-]*)d?(\d*)') - - -def nrolls(count, n): - "roll an n-sided die count times" - if n < 2: #it's a coin - if count < 5000: - return sum(random.randint(0, 1) for x in xrange(count)) - else: #fake it - return int(random.normalvariate(.5*count, (.75*count)**.5)) - else: - if count < 5000: - return sum(random.randint(1, n) for x in xrange(count)) - else: #fake it - return int(random.normalvariate(.5*(1+n)*count, - (((n+1)*(2*n+1)/6.-(.5*(1+n))**2)*count)**.5)) - - -@hook.command -def dice(inp): - ".dice -- simulates dicerolls, e.g. .dice 2d20-d5+4 roll 2 " \ - "D20s, subtract 1D5, add 4" - if not inp.strip(): - return dice.__doc__ - - spec = whitespace_re.sub('', inp) - if not valid_diceroll_re.match(spec): - return "Invalid diceroll" - sum = 0 - groups = sign_re.findall(spec) - for roll in groups: - count, side = split_re.match(roll).groups() - if side == "": - sum += int(count) - else: - count = int(count) if count not in" +-" else 1 - side = int(side) - try: - if count > 0: - sum += nrolls(count, side) - else: - sum -= nrolls(abs(count), side) - except OverflowError: - return "Thanks for overflowing a float, jerk >:[" - - return str(sum) diff --git a/plugins_available/dotnetpad.py b/plugins_available/dotnetpad.py deleted file mode 100644 index eb302b2..0000000 --- a/plugins_available/dotnetpad.py +++ /dev/null @@ -1,96 +0,0 @@ -"dotnetpad.py: by sklnd, because gobiner wouldn't shut up" - -import urllib -import httplib -import socket -import json - -from util import hook - - -def dotnetpad(lang, code): - "Posts a provided snippet of code in a provided langugage to dotnetpad.net" - - code = code.encode('utf8') - params = urllib.urlencode({'language': lang, 'code': code}) - - headers = {"Content-type": "application/x-www-form-urlencoded", - "Accept": "text/plain"} - - try: - conn = httplib.HTTPConnection("dotnetpad.net:80") - conn.request("POST", "/Skybot", params, headers) - response = conn.getresponse() - except httplib.HTTPException: - conn.close() - return 'error: dotnetpad is broken somehow' - except socket.error: - return 'error: unable to connect to dotnetpad' - - try: - result = json.loads(response.read()) - except ValueError: - conn.close() - return 'error: dotnetpad is broken somehow' - - conn.close() - - if result['Errors']: - return 'First error: %s' % (result['Errors'][0]['ErrorText']) - elif result['Output']: - return result['Output'].lstrip() - else: - return 'No output' - - -@hook.command -def fs(inp): - ".fs -- post a F# code snippet to dotnetpad.net and print the results" - - if not inp: - return fs.__doc__ - - return dotnetpad('fsharp', inp) - - -@hook.command -def cs(snippet): - ".cs -- post a C# code snippet to dotnetpad.net and print the results" - - if not snippet: - return cs.__doc__ - - file_template = ('using System; ' - 'using System.Linq; ' - 'using System.Collections.Generic; ' - 'using System.Text; ' - '%(class)s') - - class_template = ('public class Default ' - '{ ' - ' %(main)s ' - '}') - - main_template = ('public static void Main(String[] args) ' - '{ ' - ' %(snippet)s ' - '}') - - # There are probably better ways to do the following, but I'm feeling lazy - # if no main is found in the snippet, then we use the template with Main in it - if 'public static void Main' not in snippet: - code = main_template % { 'snippet': snippet } - code = class_template % { 'main': code } - code = file_template % { 'class' : code } - - # if Main is found, check for class and see if we need to use the classed template - elif 'class' not in snippet: - code = class_template % { 'main': snippet } - code = file_template % { 'class' : code } - - return 'Error using dotnetpad' - # if we found class, then use the barebones template - else: - code = file_template % { 'class' : snippet } - - return dotnetpad('csharp', code) diff --git a/plugins_available/down.py b/plugins_available/down.py deleted file mode 100644 index a6247d7..0000000 --- a/plugins_available/down.py +++ /dev/null @@ -1,27 +0,0 @@ -import urllib2 -import urlparse - -from util import hook - -@hook.command -def down(inp): - '''.down -- checks to see if the site is down''' - inp = inp.strip() - - if not inp: - return down.__doc__ - - if 'http://' not in inp: - inp = 'http://' + inp - - inp = 'http://' + urlparse.urlparse(inp).netloc - - # http://mail.python.org/pipermail/python-list/2006-December/589854.html - try: - request = urllib2.Request(inp) - request.get_method = lambda: "HEAD" - http_file = urllib2.urlopen(request) - head = http_file.read() - return inp + ' seems to be up' - except urllib2.URLError: - return inp + ' seems to be down' diff --git a/plugins_available/explain.py b/plugins_available/explain.py deleted file mode 100755 index ba24501..0000000 --- a/plugins_available/explain.py +++ /dev/null @@ -1,15 +0,0 @@ -from util import hook -from pycparser.cdecl import explain_c_declaration - -@hook.command('explain') -def explain(inp): - ".explain -- gives an explanation of C expression" - if not inp: - return explain.__doc__ - - inp = inp.encode('utf8', 'ignore') - - try: - return explain_c_declaration(inp.rstrip()) - except Exception, e: - return 'error: %s' % e diff --git a/plugins_available/google.py b/plugins_available/google.py deleted file mode 100644 index e90c874..0000000 --- a/plugins_available/google.py +++ /dev/null @@ -1,59 +0,0 @@ -import urllib -import random -from lxml import html -import json - -from util import hook - - -def api_get(kind, query): - req_url = 'http://ajax.googleapis.com/ajax/services/search/%s?' \ - 'v=1.0&safe=off&q=%s' - query = query.encode('utf8') - url = req_url % (kind, urllib.quote(query, safe='')) - page = urllib.urlopen(url).read() - return json.loads(page) - - -@hook.command -def gis(inp): - '''.gis -- returns first google image result (safesearch off)''' - if not inp: - return gis.__doc__ - - parsed = api_get('images', inp) - if not 200 <= parsed['responseStatus'] < 300: - raise IOError('error searching for images: %d: %s' % ( - parsed['responseStatus'], '')) - if not parsed['responseData']['results']: - return 'no images found' - return random.choice(parsed['responseData']['results'][:10] - )['unescapedUrl'] # squares is dumb - - -@hook.command -@hook.command('g') -def google(inp): - '''.g/.google -- returns first google search result''' - if not inp: - return google.__doc__ - - parsed = api_get('web', inp) - if not 200 <= parsed['responseStatus'] < 300: - raise IOError('error searching for pages: %d: %s' % ( - parsed['responseStatus'], '')) - if not parsed['responseData']['results']: - return 'no results found' - - result = parsed['responseData']['results'][0] - - title, content = map(lambda x: html.fromstring(x).text_content(), - (result['titleNoFormatting'], result['content'])) - - out = '%s -- \x02%s\x02: "%s"' % (result['unescapedUrl'], title, content) - out = ' '.join(out.split()) - - if len(out) > 300: - out = out[:out.rfind(' ')] + '..."' - - return out diff --git a/plugins_available/goonsay.py b/plugins_available/goonsay.py deleted file mode 100644 index 7cd3623..0000000 --- a/plugins_available/goonsay.py +++ /dev/null @@ -1,8 +0,0 @@ -from util import hook - -#Scaevolus: factormystic if you commit a re-enabled goonsay I'm going to revoke your commit access -#@hook.command -def goonsay(bot, input): - input.say(' __________ /') - input.say('(--[. ]-[ .] /') - input.say('(_______o__)') diff --git a/plugins_available/hash.py b/plugins_available/hash.py deleted file mode 100644 index 99a2b84..0000000 --- a/plugins_available/hash.py +++ /dev/null @@ -1,20 +0,0 @@ -import hashlib - -from util import hook - - -@hook.command -def md5(inp): - return hashlib.md5(inp).hexdigest() - - -@hook.command -def sha1(inp): - return hashlib.sha1(inp).hexdigest() - - -@hook.command -def hash(inp): - ".hash -- returns hashes of " - return ', '.join(x + ": " + getattr(hashlib, x)(inp).hexdigest() - for x in 'md5 sha1 sha256'.split()) diff --git a/plugins_available/help.py b/plugins_available/help.py deleted file mode 100644 index af73ce1..0000000 --- a/plugins_available/help.py +++ /dev/null @@ -1,17 +0,0 @@ -from util import hook - -@hook.command -def help(bot, input): - ".help [command] -- gives a list of commands/help for a command" - - funcs = {} - for csig, func, args in bot.plugs['command']: - if args['hook'] != r'(.*)': - if func.__doc__ is not None: - funcs[csig[1]] = func - - if not input.inp.strip(): - input.pm('available commands: ' + ' '.join(sorted(funcs))) - else: - if input.inp in funcs: - input.pm(funcs[input.inp].__doc__) diff --git a/plugins_available/log.py b/plugins_available/log.py deleted file mode 100644 index ce27906..0000000 --- a/plugins_available/log.py +++ /dev/null @@ -1,108 +0,0 @@ -""" -log.py: written by Scaevolus 2009 -""" - -import os -import thread -import codecs -import time -import re - -from util import hook - - -lock = thread.allocate_lock() -log_fds = {} # '%(net)s %(chan)s' : (filename, fd) - -timestamp_format = '%H:%M:%S' - -formats = {'PRIVMSG': '<%(nick)s> %(msg)s', - 'PART': '-!- %(nick)s [%(user)s@%(host)s] has left %(chan)s', - 'JOIN': '-!- %(nick)s [%(user)s@%(host)s] has joined %(param0)s', - 'MODE': '-!- mode/%(chan)s [%(param_tail)s] by %(nick)s', - 'KICK': '-!- %(param1)s was kicked from %(chan)s by %(nick)s [%(msg)s]', - 'TOPIC': '-!- %(nick)s changed the topic of %(chan)s to: %(msg)s', - 'QUIT': '-!- %(nick)s has quit [%(msg)s]', - 'PING': '', - 'NOTICE': '' -} - -ctcp_formats = {'ACTION': '* %(nick)s %(ctcpmsg)s'} - -irc_color_re = re.compile(r'(\x03(\d+,\d+|\d)|[\x0f\x02\x16\x1f])') - - -def get_log_filename(dir, server, chan): - return os.path.join(dir, 'log', gmtime('%Y'), server, - gmtime('%%s.%m-%d.log') % chan).lower() - - -def gmtime(format): - return time.strftime(format, time.gmtime()) - - -def beautify(input): - format = formats.get(input.command, '%(raw)s') - args = vars(input) - leng = len(args['paraml']) - for n, p in enumerate(args['paraml']): - args['param' + str(n)] = p - args['param_' + str(abs(n - leng))] = p - - args['param_tail'] = ' '.join(args['paraml'][1:]) - args['msg'] = irc_color_re.sub('', args['msg']) - - if input.command == 'PRIVMSG' and input.msg.count('\x01') >= 2: - #ctcp - ctcp = input.msg.split('\x01', 2)[1].split(' ', 1) - if len(ctcp) == 1: - ctcp += [''] - args['ctcpcmd'], args['ctcpmsg'] = ctcp - format = ctcp_formats.get(args['ctcpcmd'], - '%(nick)s [%(user)s@%(host)s] requested unknown CTCP ' - '%(ctcpcmd)s from %(chan)s: %(ctcpmsg)s') - - return format % args - - -def get_log_fd(dir, server, chan): - fn = get_log_filename(dir, server, chan) - cache_key = '%s %s' % (server, chan) - filename, fd = log_fds.get(cache_key, ('', 0)) - - if fn != filename: # we need to open a file for writing - if fd != 0: # is a valid fd - fd.flush() - fd.close() - dir = os.path.split(fn)[0] - if not os.path.exists(dir): - os.makedirs(dir) - fd = codecs.open(fn, 'a', 'utf-8') - log_fds[cache_key] = (fn, fd) - - return fd - - -@hook.tee -def log(bot, input): - with lock: - timestamp = gmtime(timestamp_format) - - fd = get_log_fd(bot.persist_dir, input.server, 'raw') - fd.write(timestamp + ' ' + input.raw + '\n') - - if input.command == 'QUIT': # these are temporary fixes until proper - input.chan = 'quit' # presence tracking is implemented - if input.command == 'NICK': - input.chan = 'nick' - - beau = beautify(input) - - if beau == '': # don't log this - return - - if input.chan: - fd = get_log_fd(bot.persist_dir, input.server, input.chan) - fd.write(timestamp + ' ' + beau + '\n') - - print timestamp, input.chan, beau.encode('utf8', 'ignore') diff --git a/plugins_available/misc.py b/plugins_available/misc.py deleted file mode 100644 index 181db84..0000000 --- a/plugins_available/misc.py +++ /dev/null @@ -1,30 +0,0 @@ -from util import hook -import socket - -socket.setdefaulttimeout(5) # global setting - - -#autorejoin channels -@hook.event('KICK') -def rejoin(bot, input): - if input.paraml[1] == input.conn.nick: - if input.paraml[0] in input.conn.channels: - input.conn.join(input.paraml[0]) - -#join channels when invited -@hook.event('INVITE') -def invite(bot, input): - if input.command == 'INVITE': - input.conn.join(input.inp) - -#join channels when server says hello & identify bot -@hook.event('004') -def onjoin(bot, input): - for channel in input.conn.channels: - input.conn.join(channel) - - nickserv_password = input.conn.conf.get('nickserv_password', '') - nickserv_name = input.conn.conf.get('nickserv_name', 'nickserv') - nickserv_command = input.conn.conf.get('nickserv_command', 'IDENTIFY %s') - if nickserv_password: - input.conn.msg(nickserv_name, nickserv_command % nickserv_password) diff --git a/plugins_available/mtg.py b/plugins_available/mtg.py deleted file mode 100644 index e3054f3..0000000 --- a/plugins_available/mtg.py +++ /dev/null @@ -1,170 +0,0 @@ -from lxml import html -import re -import urllib2 -import sys - -from util import hook - - -@hook.command -def mtg(inp): - url = 'http://magiccards.info/query.php?cardname=' - url += urllib2.quote(inp, safe='') - h = html.parse(url) - name = h.find('/body/table/tr/td/table/tr/td/h1') - if name is None: - return "no cards found" - card = name.getparent() - text = card.find('p') - - type = text.text - text = text.find('b').text_content() - text = re.sub(r'\(.*?\)', '', text) # strip parenthetical explanations - text = re.sub(r'\.(\S)', r'. \1', text) # fix spacing - - printings = card.find('table/tr/td/img').getparent().text_content() - printings = re.findall(r'\s*(.+?(?: \([^)]+\))*) \((.*?)\)', - ' '.join(printings.split())) - printing_out = ', '.join('%s (%s)' % (set_abbrevs.get(x[0], x[0]), - rarity_abbrevs.get(x[1], x[1])) - for x in printings) - - name.make_links_absolute() - link = name.find('a').attrib['href'] - name = name.text_content().strip() - type = type.strip() - text = ' '.join(text.split()) - - return ' | '.join((name, type, text, printing_out, link)) - - -set_abbrevs = { - '15th Anniversary': '15ANN', - 'APAC Junior Series': 'AJS', - 'Alara Reborn': 'ARB', - 'Alliances': 'AI', - 'Anthologies': 'AT', - 'Antiquities': 'AQ', - 'Apocalypse': 'AP', - 'Arabian Nights': 'AN', - 'Arena League': 'ARENA', - 'Asia Pacific Land Program': 'APAC', - 'Battle Royale': 'BR', - 'Beatdown': 'BD', - 'Betrayers of Kamigawa': 'BOK', - 'Celebration Cards': 'UQC', - 'Champions of Kamigawa': 'CHK', - 'Champs': 'CP', - 'Chronicles': 'CH', - 'Classic Sixth Edition': '6E', - 'Coldsnap': 'CS', - 'Coldsnap Theme Decks': 'CSTD', - 'Conflux': 'CFX', - 'Core Set - Eighth Edition': '8E', - 'Core Set - Ninth Edition': '9E', - 'Darksteel': 'DS', - 'Deckmasters': 'DM', - 'Dissension': 'DI', - 'Dragon Con': 'DRC', - 'Duel Decks: Divine vs. Demonic': 'DVD', - 'Duel Decks: Elves vs. Goblins': 'EVG', - 'Duel Decks: Garruk vs. Liliana': 'GVL', - 'Duel Decks: Jace vs. Chandra': 'JVC', - 'Eighth Edition Box Set': '8EB', - 'European Land Program': 'EURO', - 'Eventide': 'EVE', - 'Exodus': 'EX', - 'Fallen Empires': 'FE', - 'Fifth Dawn': '5DN', - 'Fifth Edition': '5E', - 'Fourth Edition': '4E', - 'Friday Night Magic': 'FNMP', - 'From the Vault: Dragons': 'FVD', - 'From the Vault: Exiled': 'FVE', - 'Future Sight': 'FUT', - 'Gateway': 'GRC', - 'Grand Prix': 'GPX', - 'Guildpact': 'GP', - 'Guru': 'GURU', - 'Happy Holidays': 'HHO', - 'Homelands': 'HL', - 'Ice Age': 'IA', - 'Introductory Two-Player Set': 'ITP', - 'Invasion': 'IN', - 'Judge Gift Program': 'JR', - 'Judgment': 'JU', - 'Junior Series': 'JSR', - 'Legend Membership': 'DCILM', - 'Legends': 'LG', - 'Legions': 'LE', - 'Limited Edition (Alpha)': 'AL', - 'Limited Edition (Beta)': 'BE', - 'Lorwyn': 'LW', - 'MTGO Masters Edition': 'MED', - 'MTGO Masters Edition II': 'ME2', - 'MTGO Masters Edition III': 'ME3', - 'Magic 2010': 'M10', - 'Magic Game Day Cards': 'MGDC', - 'Magic Player Rewards': 'MPRP', - 'Magic Scholarship Series': 'MSS', - 'Magic: The Gathering Launch Parties': 'MLP', - 'Media Inserts': 'MBP', - 'Mercadian Masques': 'MM', - 'Mirage': 'MR', - 'Mirrodin': 'MI', - 'Morningtide': 'MT', - 'Multiverse Gift Box Cards': 'MGBC', - 'Nemesis': 'NE', - 'Ninth Edition Box Set': '9EB', - 'Odyssey': 'OD', - 'Onslaught': 'ON', - 'Planar Chaos': 'PC', - 'Planechase': 'PCH', - 'Planeshift': 'PS', - 'Portal': 'PO', - 'Portal Demogame': 'POT', - 'Portal Second Age': 'PO2', - 'Portal Three Kingdoms': 'P3K', - 'Premium Deck Series: Slivers': 'PDS', - 'Prerelease Events': 'PTC', - 'Pro Tour': 'PRO', - 'Prophecy': 'PR', - 'Ravnica: City of Guilds': 'RAV', - 'Release Events': 'REP', - 'Revised Edition': 'RV', - 'Saviors of Kamigawa': 'SOK', - 'Scourge': 'SC', - 'Seventh Edition': '7E', - 'Shadowmoor': 'SHM', - 'Shards of Alara': 'ALA', - 'Starter': 'ST', - 'Starter 2000 Box Set': 'ST2K', - 'Stronghold': 'SH', - 'Summer of Magic': 'SOM', - 'Super Series': 'SUS', - 'Tempest': 'TP', - 'Tenth Edition': '10E', - 'The Dark': 'DK', - 'Time Spiral': 'TS', - 'Time Spiral Timeshifted': 'TSTS', - 'Torment': 'TR', - 'Two-Headed Giant Tournament': 'THGT', - 'Unglued': 'UG', - 'Unhinged': 'UH', - 'Unhinged Alternate Foils': 'UHAA', - 'Unlimited Edition': 'UN', - "Urza's Destiny": 'UD', - "Urza's Legacy": 'UL', - "Urza's Saga": 'US', - 'Visions': 'VI', - 'Weatherlight': 'WL', - 'Worlds': 'WRL', - 'WotC Online Store': 'WOTC', - 'Zendikar': 'ZEN'} - -rarity_abbrevs = { - 'Common': 'C', - 'Uncommon': 'UC', - 'Rare': 'R', - 'Special': 'S', - 'Mythic Rare': 'MR'} diff --git a/plugins_available/profile.py b/plugins_available/profile.py deleted file mode 100644 index a6faee2..0000000 --- a/plugins_available/profile.py +++ /dev/null @@ -1,13 +0,0 @@ -# for crusty old rotor - -from util import hook - - -@hook.command -def profile(inp): - ".profile -- links to 's profile on SA" - if not inp: - return profile.__doc__ - - return 'http://forums.somethingawful.com/member.php?action=getinfo' + \ - '&username=' + '+'.join(inp.split()) diff --git a/plugins_available/pycparser/__init__.py b/plugins_available/pycparser/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/plugins_available/pycparser/cdecl.py b/plugins_available/pycparser/cdecl.py deleted file mode 100644 index c0dc5b3..0000000 --- a/plugins_available/pycparser/cdecl.py +++ /dev/null @@ -1,98 +0,0 @@ -#----------------------------------------------------------------- -# pycparser: cdecl.py -# -# Example of the CDECL tool using pycparser. CDECL "explains" -# C type declarations in plain English. -# -# The AST generated by pycparser from the given declaration is -# traversed recursively to build the explanation. -# Note that the declaration must be a valid external declaration -# in C. All the types used in it must be defined with typedef, -# or parsing will fail. The definition can be arbitrary, it isn't -# really used - by pycparser must know which tokens are types. -# -# For example: -# -# 'typedef int Node; const Node* (*ar)[10];' -# => -# ar is a pointer to array[10] of pointer to const Node -# -# Copyright (C) 2008, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- -import sys - -from pycparser import c_parser, c_ast - - -def explain_c_declaration(c_decl): - """ Parses the declaration in c_decl and returns a text - explanation as a string. - - The last external node of the string is used, to allow - earlier typedefs for used types. - """ - parser = c_parser.CParser() - - node = parser.parse(c_decl, filename='') - - if ( not isinstance(node, c_ast.FileAST) or - not isinstance(node.ext[-1], c_ast.Decl)): - return "Last external node is invalid type" - - return _explain_decl_node(node.ext[-1]) - - -def _explain_decl_node(decl_node): - """ Receives a c_ast.Decl note and returns its explanation in - English. - """ - #~ print decl_node.show() - storage = ' '.join(decl_node.storage) + ' ' if decl_node.storage else '' - - return (decl_node.name + - " is a " + - storage + - _explain_type(decl_node.type)) - - -def _explain_type(decl): - """ Recursively explains a type decl node - """ - typ = type(decl) - - if typ == c_ast.TypeDecl: - quals = ' '.join(decl.quals) + ' ' if decl.quals else '' - return quals + _explain_type(decl.type) - elif typ == c_ast.Typename or typ == c_ast.Decl: - return _explain_type(decl.type) - elif typ == c_ast.IdentifierType: - return ' '.join(decl.names) - elif typ == c_ast.PtrDecl: - quals = ' '.join(decl.quals) + ' ' if decl.quals else '' - return quals + 'pointer to ' + _explain_type(decl.type) - elif typ == c_ast.ArrayDecl: - arr = 'array' - if decl.dim: arr += '[%s]' % decl.dim.value - - return arr + " of " + _explain_type(decl.type) - - elif typ == c_ast.FuncDecl: - if decl.args: - params = [_explain_type(param) for param in decl.args.params] - args = ', '.join(params) - else: - args = '' - - return ('function(%s) returning ' % (args) + - _explain_type(decl.type)) - - -if __name__ == "__main__": - if len(sys.argv) > 1: - c_decl = sys.argv[1] - else: - c_decl = "char *(*(**foo[][8])())[];" - - print "Explaining the declaration:", c_decl - print "\n", explain_c_declaration(c_decl) diff --git a/plugins_available/pycparser/lextab.py b/plugins_available/pycparser/lextab.py deleted file mode 100644 index f33ce0c..0000000 --- a/plugins_available/pycparser/lextab.py +++ /dev/null @@ -1,9 +0,0 @@ -# pycparser.lextab.py. This file automatically created by PLY (version 3.3). Don't edit! -_tabversion = '3.3' -_lextokens = {'VOID': 1, 'LBRACKET': 1, 'WCHAR_CONST': 1, 'FLOAT_CONST': 1, 'MINUS': 1, 'RPAREN': 1, 'LONG': 1, 'PLUS': 1, 'ELLIPSIS': 1, 'GT': 1, 'GOTO': 1, 'ENUM': 1, 'PERIOD': 1, 'GE': 1, 'INT_CONST_DEC': 1, 'ARROW': 1, 'DOUBLE': 1, 'MINUSEQUAL': 1, 'INT_CONST_OCT': 1, 'TIMESEQUAL': 1, 'OR': 1, 'SHORT': 1, 'RETURN': 1, 'RSHIFTEQUAL': 1, 'STATIC': 1, 'SIZEOF': 1, 'UNSIGNED': 1, 'UNION': 1, 'COLON': 1, 'WSTRING_LITERAL': 1, 'DIVIDE': 1, 'FOR': 1, 'PLUSPLUS': 1, 'EQUALS': 1, 'ELSE': 1, 'EQ': 1, 'AND': 1, 'TYPEID': 1, 'LBRACE': 1, 'PPHASH': 1, 'INT': 1, 'SIGNED': 1, 'CONTINUE': 1, 'NOT': 1, 'OREQUAL': 1, 'MOD': 1, 'RSHIFT': 1, 'DEFAULT': 1, 'CHAR': 1, 'WHILE': 1, 'DIVEQUAL': 1, 'EXTERN': 1, 'CASE': 1, 'LAND': 1, 'REGISTER': 1, 'MODEQUAL': 1, 'NE': 1, 'SWITCH': 1, 'INT_CONST_HEX': 1, 'PLUSEQUAL': 1, 'STRUCT': 1, 'CONDOP': 1, 'BREAK': 1, 'VOLATILE': 1, 'ANDEQUAL': 1, 'DO': 1, 'LNOT': 1, 'CONST': 1, 'LOR': 1, 'CHAR_CONST': 1, 'LSHIFT': 1, 'RBRACE': 1, 'LE': 1, 'SEMI': 1, 'LT': 1, 'COMMA': 1, 'TYPEDEF': 1, 'XOR': 1, 'AUTO': 1, 'TIMES': 1, 'LPAREN': 1, 'MINUSMINUS': 1, 'ID': 1, 'IF': 1, 'STRING_LITERAL': 1, 'FLOAT': 1, 'XOREQUAL': 1, 'LSHIFTEQUAL': 1, 'RBRACKET': 1} -_lexreflags = 0 -_lexliterals = '' -_lexstateinfo = {'ppline': 'exclusive', 'INITIAL': 'inclusive'} -_lexstatere = {'ppline': [('(?P"([^"\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*")|(?P(0(([uU][lL])|([lL][uU])|[uU]|[lL])?)|([1-9][0-9]*(([uU][lL])|([lL][uU])|[uU]|[lL])?))|(?P\\n)|(?Pline)', [None, ('t_ppline_FILENAME', 'FILENAME'), None, None, None, None, None, None, ('t_ppline_LINE_NUMBER', 'LINE_NUMBER'), None, None, None, None, None, None, None, None, ('t_ppline_NEWLINE', 'NEWLINE'), ('t_ppline_PPLINE', 'PPLINE')])], 'INITIAL': [('(?P[ \\t]*\\#)|(?P\\n+)|(?P((((([0-9]*\\.[0-9]+)|([0-9]+\\.))([eE][-+]?[0-9]+)?)|([0-9]+([eE][-+]?[0-9]+)))[FfLl]?))|(?P0[xX][0-9a-fA-F]+(([uU][lL])|([lL][uU])|[uU]|[lL])?)|(?P0[0-7]*[89])|(?P0[0-7]*(([uU][lL])|([lL][uU])|[uU]|[lL])?)|(?P(0(([uU][lL])|([lL][uU])|[uU]|[lL])?)|([1-9][0-9]*(([uU][lL])|([lL][uU])|[uU]|[lL])?))|(?P\'([^\'\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))\')|(?PL\'([^\'\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))\')|(?P(\'([^\'\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*\\n)|(\'([^\'\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*$))|(?P(\'([^\'\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))[^\'\n]+\')|(\'\')|(\'([\\\\][^a-zA-Z\\\\?\'"x0-7])[^\'\\n]*\'))|(?PL"([^"\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*")|(?P"([^"\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*([\\\\][^a-zA-Z\\\\?\'"x0-7])([^"\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*")|(?P[a-zA-Z_][0-9a-zA-Z_]*)|(?P"([^"\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*")', [None, ('t_PPHASH', 'PPHASH'), ('t_NEWLINE', 'NEWLINE'), ('t_FLOAT_CONST', 'FLOAT_CONST'), None, None, None, None, None, None, None, None, None, ('t_INT_CONST_HEX', 'INT_CONST_HEX'), None, None, None, ('t_BAD_CONST_OCT', 'BAD_CONST_OCT'), ('t_INT_CONST_OCT', 'INT_CONST_OCT'), None, None, None, ('t_INT_CONST_DEC', 'INT_CONST_DEC'), None, None, None, None, None, None, None, None, ('t_CHAR_CONST', 'CHAR_CONST'), None, None, None, None, None, None, ('t_WCHAR_CONST', 'WCHAR_CONST'), None, None, None, None, None, None, ('t_UNMATCHED_QUOTE', 'UNMATCHED_QUOTE'), None, None, None, None, None, None, None, None, None, None, None, None, None, None, ('t_BAD_CHAR_CONST', 'BAD_CHAR_CONST'), None, None, None, None, None, None, None, None, None, None, ('t_WSTRING_LITERAL', 'WSTRING_LITERAL'), None, None, None, None, None, None, ('t_BAD_STRING_LITERAL', 'BAD_STRING_LITERAL'), None, None, None, None, None, None, None, None, None, None, None, None, None, ('t_ID', 'ID'), (None, 'STRING_LITERAL')]), ('(?P\\.\\.\\.)|(?P\\+\\+)|(?P\\|\\|)|(?P\\|=)|(?P<<=)|(?P>>=)|(?P\\*=)|(?P\\+=)|(?P^=)|(?P\\+)|(?P%=)|(?P\\{)|(?P/=)|(?P\\])|(?P\\?)', [None, (None, 'ELLIPSIS'), (None, 'PLUSPLUS'), (None, 'LOR'), (None, 'OREQUAL'), (None, 'LSHIFTEQUAL'), (None, 'RSHIFTEQUAL'), (None, 'TIMESEQUAL'), (None, 'PLUSEQUAL'), (None, 'XOREQUAL'), (None, 'PLUS'), (None, 'MODEQUAL'), (None, 'LBRACE'), (None, 'DIVEQUAL'), (None, 'RBRACKET'), (None, 'CONDOP')]), ('(?P\\^)|(?P<<)|(?P<=)|(?P\\()|(?P->)|(?P==)|(?P\\})|(?P!=)|(?P--)|(?P\\|)|(?P\\*)|(?P\\[)|(?P>=)|(?P\\))|(?P&&)|(?P>>)|(?P&=)|(?P-=)|(?P\\.)|(?P=)|(?P<)|(?P,)|(?P/)|(?P&)|(?P%)|(?P;)|(?P-)|(?P>)|(?P:)|(?P~)|(?P!)', [None, (None, 'XOR'), (None, 'LSHIFT'), (None, 'LE'), (None, 'LPAREN'), (None, 'ARROW'), (None, 'EQ'), (None, 'RBRACE'), (None, 'NE'), (None, 'MINUSMINUS'), (None, 'OR'), (None, 'TIMES'), (None, 'LBRACKET'), (None, 'GE'), (None, 'RPAREN'), (None, 'LAND'), (None, 'RSHIFT'), (None, 'ANDEQUAL'), (None, 'MINUSEQUAL'), (None, 'PERIOD'), (None, 'EQUALS'), (None, 'LT'), (None, 'COMMA'), (None, 'DIVIDE'), (None, 'AND'), (None, 'MOD'), (None, 'SEMI'), (None, 'MINUS'), (None, 'GT'), (None, 'COLON'), (None, 'NOT'), (None, 'LNOT')])]} -_lexstateignore = {'ppline': ' \t', 'INITIAL': ' \t'} -_lexstateerrorf = {'ppline': 't_ppline_error', 'INITIAL': 't_error'} diff --git a/plugins_available/pycparser/pycparser/__init__.py b/plugins_available/pycparser/pycparser/__init__.py deleted file mode 100644 index 6219bb2..0000000 --- a/plugins_available/pycparser/pycparser/__init__.py +++ /dev/null @@ -1,75 +0,0 @@ -#----------------------------------------------------------------- -# pycparser: __init__.py -# -# This package file exports some convenience functions for -# interacting with pycparser -# -# Copyright (C) 2008-2009, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - -__all__ = ['c_lexer', 'c_parser', 'c_ast'] -__version__ = '1.05' - -from subprocess import Popen, PIPE -from types import ListType - -from c_parser import CParser - - -def parse_file( filename, use_cpp=False, - cpp_path='cpp', cpp_args=''): - """ Parse a C file using pycparser. - - filename: - Name of the file you want to parse. - - use_cpp: - Set to True if you want to execute the C pre-processor - on the file prior to parsing it. - - cpp_path: - If use_cpp is True, this is the path to 'cpp' on your - system. If no path is provided, it attempts to just - execute 'cpp', so it must be in your PATH. - - cpp_args: - If use_cpp is True, set this to the command line - arguments strings to cpp. Be careful with quotes - - it's best to pass a raw string (r'') here. - For example: - r'-I../utils/fake_libc_include' - If several arguments are required, pass a list of - strings. - - When successful, an AST is returned. ParseError can be - thrown if the file doesn't parse successfully. - - Errors from cpp will be printed out. - """ - if use_cpp: - path_list = [cpp_path] - if isinstance(cpp_args, ListType): - path_list += cpp_args - elif cpp_args != '': - path_list += [cpp_args] - path_list += [filename] - - # Note the use of universal_newlines to treat all newlines - # as \n for Python's purpose - # - pipe = Popen( path_list, - stdout=PIPE, - universal_newlines=True) - text = pipe.communicate()[0] - else: - text = open(filename).read() - - parser = CParser() - return parser.parse(text, filename) - - -if __name__ == "__main__": - pass - - diff --git a/plugins_available/pycparser/pycparser/_ast_gen.py b/plugins_available/pycparser/pycparser/_ast_gen.py deleted file mode 100644 index 47ba148..0000000 --- a/plugins_available/pycparser/pycparser/_ast_gen.py +++ /dev/null @@ -1,249 +0,0 @@ -#----------------------------------------------------------------- -# _ast_gen.py -# -# Generates the AST Node classes from a specification given in -# a .yaml file -# -# The design of this module was inspired by astgen.py from the -# Python 2.5 code-base. -# -# Copyright (C) 2008-2009, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - -import pprint -from string import Template - -import yaml - - -class ASTCodeGenerator(object): - def __init__(self, cfg_filename='_c_ast.yaml'): - """ Initialize the code generator from a configuration - file. - """ - self.cfg_filename = cfg_filename - cfg = yaml.load(open(cfg_filename).read()) - self.node_cfg = [NodeCfg(name, cfg[name]) for name in cfg] - - #~ pprint.pprint(self.node_cfg) - #~ print '' - - def generate(self, file=None): - """ Generates the code into file, an open file buffer. - """ - src = Template(_PROLOGUE_COMMENT).substitute( - cfg_filename=self.cfg_filename) - - src += _PROLOGUE_CODE - for node_cfg in self.node_cfg: - src += node_cfg.generate_source() + '\n\n' - - file.write(src) - - -class NodeCfg(object): - def __init__(self, name, contents): - self.name = name - self.all_entries = [] - self.attr = [] - self.child = [] - self.seq_child = [] - - for entry in contents: - clean_entry = entry.rstrip('*') - self.all_entries.append(clean_entry) - - if entry.endswith('**'): - self.seq_child.append(clean_entry) - elif entry.endswith('*'): - self.child.append(clean_entry) - else: - self.attr.append(entry) - - def generate_source(self): - src = self._gen_init() - src += '\n' + self._gen_children() - src += '\n' + self._gen_show() - return src - - def _gen_init(self): - src = "class %s(Node):\n" % self.name - - if self.all_entries: - args = ', '.join(self.all_entries) - arglist = '(self, %s, coord=None)' % args - else: - arglist = '(self, coord=None)' - - src += " def __init__%s:\n" % arglist - - for name in self.all_entries + ['coord']: - src += " self.%s = %s\n" % (name, name) - - return src - - def _gen_children(self): - src = ' def children(self):\n' - - if self.all_entries: - src += ' nodelist = []\n' - - template = ('' + - ' if self.%s is not None:' + - ' nodelist.%s(self.%s)\n') - - for child in self.child: - src += template % ( - child, 'append', child) - - for seq_child in self.seq_child: - src += template % ( - seq_child, 'extend', seq_child) - - src += ' return tuple(nodelist)\n' - else: - src += ' return ()\n' - - return src - - def _gen_show(self): - src = ' def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False):\n' - src += " lead = ' ' * offset\n" - - src += " buf.write(lead + '%s: ')\n\n" % self.name - - if self.attr: - src += " if attrnames:\n" - src += " attrstr = ', '.join('%s=%s' % nv for nv in [" - src += ', '.join('("%s", repr(%s))' % (nv, 'self.%s' % nv) for nv in self.attr) - src += '])\n' - src += " else:\n" - src += " attrstr = ', '.join('%s' % v for v in [" - src += ', '.join('self.%s' % v for v in self.attr) - src += '])\n' - src += " buf.write(attrstr)\n\n" - - src += " if showcoord:\n" - src += " buf.write(' (at %s)' % self.coord)\n" - src += " buf.write('\\n')\n\n" - - src += " for c in self.children():\n" - src += " c.show(buf, offset + 2, attrnames, showcoord)\n" - - return src - - -_PROLOGUE_COMMENT = \ -r'''#----------------------------------------------------------------- -# ** ATTENTION ** -# This code was automatically generated from the file: -# $cfg_filename -# -# Do not modify it directly. Modify the configuration file and -# run the generator again. -# ** ** *** ** ** -# -# pycparser: c_ast.py -# -# AST Node classes. -# -# Copyright (C) 2008, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - -''' - -_PROLOGUE_CODE = r''' -import sys - - -class Node(object): - """ Abstract base class for AST nodes. - """ - def children(self): - """ A sequence of all children that are Nodes - """ - pass - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - """ Pretty print the Node and all its attributes and - children (recursively) to a buffer. - - file: - Open IO buffer into which the Node is printed. - - offset: - Initial offset (amount of leading spaces) - - attrnames: - True if you want to see the attribute names in - name=value pairs. False to only see the values. - - showcoord: - Do you want the coordinates of each Node to be - displayed. - """ - pass - - -class NodeVisitor(object): - """ A base NodeVisitor class for visiting c_ast nodes. - Subclass it and define your own visit_XXX methods, where - XXX is the class name you want to visit with these - methods. - - For example: - - class ConstantVisitor(NodeVisitor): - def __init__(self): - self.values = [] - - def visit_Constant(self, node): - self.values.append(node.value) - - Creates a list of values of all the constant nodes - encountered below the given node. To use it: - - cv = ConstantVisitor() - cv.visit(node) - - Notes: - - * generic_visit() will be called for AST nodes for which - no visit_XXX method was defined. - * The children of nodes for which a visit_XXX was - defined will not be visited - if you need this, call - generic_visit() on the node. - You can use: - NodeVisitor.generic_visit(self, node) - * Modeled after Python's own AST visiting facilities - (the ast module of Python 3.0) - """ - def visit(self, node): - """ Visit a node. - """ - method = 'visit_' + node.__class__.__name__ - visitor = getattr(self, method, self.generic_visit) - return visitor(node) - - def generic_visit(self, node): - """ Called if no explicit visitor function exists for a - node. Implements preorder visiting of the node. - """ - for c in node.children(): - self.visit(c) - - -''' - - - -if __name__ == "__main__": - import sys - - ast_gen = ASTCodeGenerator('_c_ast.yaml') - ast_gen.generate(open('c_ast.py', 'w')) - - - diff --git a/plugins_available/pycparser/pycparser/_build_tables.py b/plugins_available/pycparser/pycparser/_build_tables.py deleted file mode 100644 index 0f02387..0000000 --- a/plugins_available/pycparser/pycparser/_build_tables.py +++ /dev/null @@ -1,31 +0,0 @@ -#----------------------------------------------------------------- -# pycparser: _build_tables.py -# -# A dummy for generating the lexing/parsing tables and and -# compiling them into .pyc for faster execution in optimized mode. -# Also generates AST code from the _c_ast.yaml configuration file. -# -# Copyright (C) 2008, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - -# Generate c_ast.py -# -from _ast_gen import ASTCodeGenerator -ast_gen = ASTCodeGenerator('_c_ast.yaml') -ast_gen.generate(open('c_ast.py', 'w')) - -import c_parser - -# Generates the tables -# -c_parser.CParser( - lex_optimize=True, - yacc_debug=False, - yacc_optimize=True) - -# Load to compile into .pyc -# -import lextab -import yacctab -import c_ast diff --git a/plugins_available/pycparser/pycparser/_c_ast.yaml b/plugins_available/pycparser/pycparser/_c_ast.yaml deleted file mode 100644 index c954e38..0000000 --- a/plugins_available/pycparser/pycparser/_c_ast.yaml +++ /dev/null @@ -1,164 +0,0 @@ -#----------------------------------------------------------------- -# pycparser: _c_ast_gen.yaml -# -# Defines the AST Node classes used in pycparser. -# -# Each entry is a Node sub-class name, listing the attributes -# and child nodes of the class: -# * - a child node -# ** - a sequence of child nodes -# - an attribute -# -# Copyright (C) 2008-2009, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - - -ArrayDecl: [type*, dim*] - -ArrayRef: [name*, subscript*] - -# op: =, +=, /= etc. -# -Assignment: [op, lvalue*, rvalue*] - -BinaryOp: [op, left*, right*] - -Break: [] - -Case: [expr*, stmt*] - -Cast: [to_type*, expr*] - -# Compound statement: { declarations... statements...} -# -Compound: [decls**, stmts**] - -# type: int, char, float, etc. see CLexer for constant token types -# -Constant: [type, value] - -Continue: [] - -# name: the variable being declared -# quals: list of qualifiers (const, volatile) -# storage: list of storage specifiers (extern, register, etc.) -# type: declaration type (probably nested with all the modifiers) -# init: initialization value, or None -# bitsize: bit field size, or None -# -Decl: [name, quals, storage, type*, init*, bitsize*] - -Default: [stmt*] - -DoWhile: [cond*, stmt*] - -# Represents the ellipsis (...) parameter in a function -# declaration -# -EllipsisParam: [] - -# Enumeration type specifier -# name: an optional ID -# values: an EnumeratorList -# -Enum: [name, values*] - -# A name/value pair for enumeration values -# -Enumerator: [name, value*] - -# A list of enumerators -# -EnumeratorList: [enumerators**] - -# a list of comma separated expressions -# -ExprList: [exprs**] - -# This is the top of the AST, representing a single C file (a -# translation unit in K&R jargon). It contains a list of -# "external-declaration"s, which is either declarations (Decl), -# Typedef or function definitions (FuncDef). -# -FileAST: [ext**] - -# for (init; cond; next) stmt -# -For: [init*, cond*, next*, stmt*] - -# name: Id -# args: ExprList -# -FuncCall: [name*, args*] - -# type (args) -# -FuncDecl: [args*, type*] - -# Function definition: a declarator for the function name and -# a body, which is a compound statement. -# There's an optional list of parameter declarations for old -# K&R-style definitions -# -FuncDef: [decl*, param_decls**, body*] - -Goto: [name] - -ID: [name] - -# Holder for types that are a simple identifier (e.g. the built -# ins void, char etc. and typedef-defined types) -# -IdentifierType: [names] - -If: [cond*, iftrue*, iffalse*] - -Label: [name, stmt*] - -# a list of comma separated function parameter declarations -# -ParamList: [params**] - -PtrDecl: [quals, type*] - -Return: [expr*] - -# name: struct tag name -# decls: declaration of members -# -Struct: [name, decls**] - -# type: . or -> -# name.field or name->field -# -StructRef: [name*, type, field*] - -Switch: [cond*, stmt*] - -# cond ? iftrue : iffalse -# -TernaryOp: [cond*, iftrue*, iffalse*] - -# A base type declaration -# -TypeDecl: [declname, quals, type*] - -# A typedef declaration. -# Very similar to Decl, but without some attributes -# -Typedef: [name, quals, storage, type*] - -Typename: [quals, type*] - -UnaryOp: [op, expr*] - -# name: union tag name -# decls: declaration of members -# -Union: [name, decls**] - -While: [cond*, stmt*] - - - diff --git a/plugins_available/pycparser/pycparser/c_ast.py b/plugins_available/pycparser/pycparser/c_ast.py deleted file mode 100644 index 90cfb79..0000000 --- a/plugins_available/pycparser/pycparser/c_ast.py +++ /dev/null @@ -1,1163 +0,0 @@ -#----------------------------------------------------------------- -# ** ATTENTION ** -# This code was automatically generated from the file: -# _c_ast.yaml -# -# Do not modify it directly. Modify the configuration file and -# run the generator again. -# ** ** *** ** ** -# -# pycparser: c_ast.py -# -# AST Node classes. -# -# Copyright (C) 2008, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - - -import sys - - -class Node(object): - """ Abstract base class for AST nodes. - """ - def children(self): - """ A sequence of all children that are Nodes - """ - pass - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - """ Pretty print the Node and all its attributes and - children (recursively) to a buffer. - - file: - Open IO buffer into which the Node is printed. - - offset: - Initial offset (amount of leading spaces) - - attrnames: - True if you want to see the attribute names in - name=value pairs. False to only see the values. - - showcoord: - Do you want the coordinates of each Node to be - displayed. - """ - pass - - -class NodeVisitor(object): - """ A base NodeVisitor class for visiting c_ast nodes. - Subclass it and define your own visit_XXX methods, where - XXX is the class name you want to visit with these - methods. - - For example: - - class ConstantVisitor(NodeVisitor): - def __init__(self): - self.values = [] - - def visit_Constant(self, node): - self.values.append(node.value) - - Creates a list of values of all the constant nodes - encountered below the given node. To use it: - - cv = ConstantVisitor() - cv.visit(node) - - Notes: - - * generic_visit() will be called for AST nodes for which - no visit_XXX method was defined. - * The children of nodes for which a visit_XXX was - defined will not be visited - if you need this, call - generic_visit() on the node. - You can use: - NodeVisitor.generic_visit(self, node) - * Modeled after Python's own AST visiting facilities - (the ast module of Python 3.0) - """ - def visit(self, node): - """ Visit a node. - """ - method = 'visit_' + node.__class__.__name__ - visitor = getattr(self, method, self.generic_visit) - return visitor(node) - - def generic_visit(self, node): - """ Called if no explicit visitor function exists for a - node. Implements preorder visiting of the node. - """ - for c in node.children(): - self.visit(c) - - -class Typedef(Node): - def __init__(self, name, quals, storage, type, coord=None): - self.name = name - self.quals = quals - self.storage = storage - self.type = type - self.coord = coord - - def children(self): - nodelist = [] - if self.type is not None: nodelist.append(self.type) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Typedef: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name)), ("quals", repr(self.quals)), ("storage", repr(self.storage))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name, self.quals, self.storage]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Struct(Node): - def __init__(self, name, decls, coord=None): - self.name = name - self.decls = decls - self.coord = coord - - def children(self): - nodelist = [] - if self.decls is not None: nodelist.extend(self.decls) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Struct: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class FuncCall(Node): - def __init__(self, name, args, coord=None): - self.name = name - self.args = args - self.coord = coord - - def children(self): - nodelist = [] - if self.name is not None: nodelist.append(self.name) - if self.args is not None: nodelist.append(self.args) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'FuncCall: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class UnaryOp(Node): - def __init__(self, op, expr, coord=None): - self.op = op - self.expr = expr - self.coord = coord - - def children(self): - nodelist = [] - if self.expr is not None: nodelist.append(self.expr) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'UnaryOp: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("op", repr(self.op))]) - else: - attrstr = ', '.join('%s' % v for v in [self.op]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Union(Node): - def __init__(self, name, decls, coord=None): - self.name = name - self.decls = decls - self.coord = coord - - def children(self): - nodelist = [] - if self.decls is not None: nodelist.extend(self.decls) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Union: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class TernaryOp(Node): - def __init__(self, cond, iftrue, iffalse, coord=None): - self.cond = cond - self.iftrue = iftrue - self.iffalse = iffalse - self.coord = coord - - def children(self): - nodelist = [] - if self.cond is not None: nodelist.append(self.cond) - if self.iftrue is not None: nodelist.append(self.iftrue) - if self.iffalse is not None: nodelist.append(self.iffalse) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'TernaryOp: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Label(Node): - def __init__(self, name, stmt, coord=None): - self.name = name - self.stmt = stmt - self.coord = coord - - def children(self): - nodelist = [] - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Label: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class IdentifierType(Node): - def __init__(self, names, coord=None): - self.names = names - self.coord = coord - - def children(self): - nodelist = [] - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'IdentifierType: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("names", repr(self.names))]) - else: - attrstr = ', '.join('%s' % v for v in [self.names]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class FuncDef(Node): - def __init__(self, decl, param_decls, body, coord=None): - self.decl = decl - self.param_decls = param_decls - self.body = body - self.coord = coord - - def children(self): - nodelist = [] - if self.decl is not None: nodelist.append(self.decl) - if self.body is not None: nodelist.append(self.body) - if self.param_decls is not None: nodelist.extend(self.param_decls) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'FuncDef: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Enumerator(Node): - def __init__(self, name, value, coord=None): - self.name = name - self.value = value - self.coord = coord - - def children(self): - nodelist = [] - if self.value is not None: nodelist.append(self.value) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Enumerator: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class For(Node): - def __init__(self, init, cond, next, stmt, coord=None): - self.init = init - self.cond = cond - self.next = next - self.stmt = stmt - self.coord = coord - - def children(self): - nodelist = [] - if self.init is not None: nodelist.append(self.init) - if self.cond is not None: nodelist.append(self.cond) - if self.next is not None: nodelist.append(self.next) - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'For: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Assignment(Node): - def __init__(self, op, lvalue, rvalue, coord=None): - self.op = op - self.lvalue = lvalue - self.rvalue = rvalue - self.coord = coord - - def children(self): - nodelist = [] - if self.lvalue is not None: nodelist.append(self.lvalue) - if self.rvalue is not None: nodelist.append(self.rvalue) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Assignment: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("op", repr(self.op))]) - else: - attrstr = ', '.join('%s' % v for v in [self.op]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class FuncDecl(Node): - def __init__(self, args, type, coord=None): - self.args = args - self.type = type - self.coord = coord - - def children(self): - nodelist = [] - if self.args is not None: nodelist.append(self.args) - if self.type is not None: nodelist.append(self.type) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'FuncDecl: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Enum(Node): - def __init__(self, name, values, coord=None): - self.name = name - self.values = values - self.coord = coord - - def children(self): - nodelist = [] - if self.values is not None: nodelist.append(self.values) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Enum: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class ExprList(Node): - def __init__(self, exprs, coord=None): - self.exprs = exprs - self.coord = coord - - def children(self): - nodelist = [] - if self.exprs is not None: nodelist.extend(self.exprs) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'ExprList: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Break(Node): - def __init__(self, coord=None): - self.coord = coord - - def children(self): - return () - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Break: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class DoWhile(Node): - def __init__(self, cond, stmt, coord=None): - self.cond = cond - self.stmt = stmt - self.coord = coord - - def children(self): - nodelist = [] - if self.cond is not None: nodelist.append(self.cond) - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'DoWhile: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class StructRef(Node): - def __init__(self, name, type, field, coord=None): - self.name = name - self.type = type - self.field = field - self.coord = coord - - def children(self): - nodelist = [] - if self.name is not None: nodelist.append(self.name) - if self.field is not None: nodelist.append(self.field) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'StructRef: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("type", repr(self.type))]) - else: - attrstr = ', '.join('%s' % v for v in [self.type]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class BinaryOp(Node): - def __init__(self, op, left, right, coord=None): - self.op = op - self.left = left - self.right = right - self.coord = coord - - def children(self): - nodelist = [] - if self.left is not None: nodelist.append(self.left) - if self.right is not None: nodelist.append(self.right) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'BinaryOp: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("op", repr(self.op))]) - else: - attrstr = ', '.join('%s' % v for v in [self.op]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Compound(Node): - def __init__(self, decls, stmts, coord=None): - self.decls = decls - self.stmts = stmts - self.coord = coord - - def children(self): - nodelist = [] - if self.decls is not None: nodelist.extend(self.decls) - if self.stmts is not None: nodelist.extend(self.stmts) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Compound: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class ArrayDecl(Node): - def __init__(self, type, dim, coord=None): - self.type = type - self.dim = dim - self.coord = coord - - def children(self): - nodelist = [] - if self.type is not None: nodelist.append(self.type) - if self.dim is not None: nodelist.append(self.dim) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'ArrayDecl: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Case(Node): - def __init__(self, expr, stmt, coord=None): - self.expr = expr - self.stmt = stmt - self.coord = coord - - def children(self): - nodelist = [] - if self.expr is not None: nodelist.append(self.expr) - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Case: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Cast(Node): - def __init__(self, to_type, expr, coord=None): - self.to_type = to_type - self.expr = expr - self.coord = coord - - def children(self): - nodelist = [] - if self.to_type is not None: nodelist.append(self.to_type) - if self.expr is not None: nodelist.append(self.expr) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Cast: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class TypeDecl(Node): - def __init__(self, declname, quals, type, coord=None): - self.declname = declname - self.quals = quals - self.type = type - self.coord = coord - - def children(self): - nodelist = [] - if self.type is not None: nodelist.append(self.type) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'TypeDecl: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("declname", repr(self.declname)), ("quals", repr(self.quals))]) - else: - attrstr = ', '.join('%s' % v for v in [self.declname, self.quals]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Default(Node): - def __init__(self, stmt, coord=None): - self.stmt = stmt - self.coord = coord - - def children(self): - nodelist = [] - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Default: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class PtrDecl(Node): - def __init__(self, quals, type, coord=None): - self.quals = quals - self.type = type - self.coord = coord - - def children(self): - nodelist = [] - if self.type is not None: nodelist.append(self.type) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'PtrDecl: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("quals", repr(self.quals))]) - else: - attrstr = ', '.join('%s' % v for v in [self.quals]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Switch(Node): - def __init__(self, cond, stmt, coord=None): - self.cond = cond - self.stmt = stmt - self.coord = coord - - def children(self): - nodelist = [] - if self.cond is not None: nodelist.append(self.cond) - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Switch: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Continue(Node): - def __init__(self, coord=None): - self.coord = coord - - def children(self): - return () - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Continue: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class ParamList(Node): - def __init__(self, params, coord=None): - self.params = params - self.coord = coord - - def children(self): - nodelist = [] - if self.params is not None: nodelist.extend(self.params) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'ParamList: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Return(Node): - def __init__(self, expr, coord=None): - self.expr = expr - self.coord = coord - - def children(self): - nodelist = [] - if self.expr is not None: nodelist.append(self.expr) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Return: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Typename(Node): - def __init__(self, quals, type, coord=None): - self.quals = quals - self.type = type - self.coord = coord - - def children(self): - nodelist = [] - if self.type is not None: nodelist.append(self.type) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Typename: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("quals", repr(self.quals))]) - else: - attrstr = ', '.join('%s' % v for v in [self.quals]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class ID(Node): - def __init__(self, name, coord=None): - self.name = name - self.coord = coord - - def children(self): - nodelist = [] - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'ID: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Goto(Node): - def __init__(self, name, coord=None): - self.name = name - self.coord = coord - - def children(self): - nodelist = [] - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Goto: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Decl(Node): - def __init__(self, name, quals, storage, type, init, bitsize, coord=None): - self.name = name - self.quals = quals - self.storage = storage - self.type = type - self.init = init - self.bitsize = bitsize - self.coord = coord - - def children(self): - nodelist = [] - if self.type is not None: nodelist.append(self.type) - if self.init is not None: nodelist.append(self.init) - if self.bitsize is not None: nodelist.append(self.bitsize) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Decl: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name)), ("quals", repr(self.quals)), ("storage", repr(self.storage))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name, self.quals, self.storage]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Constant(Node): - def __init__(self, type, value, coord=None): - self.type = type - self.value = value - self.coord = coord - - def children(self): - nodelist = [] - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Constant: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("type", repr(self.type)), ("value", repr(self.value))]) - else: - attrstr = ', '.join('%s' % v for v in [self.type, self.value]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class FileAST(Node): - def __init__(self, ext, coord=None): - self.ext = ext - self.coord = coord - - def children(self): - nodelist = [] - if self.ext is not None: nodelist.extend(self.ext) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'FileAST: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class ArrayRef(Node): - def __init__(self, name, subscript, coord=None): - self.name = name - self.subscript = subscript - self.coord = coord - - def children(self): - nodelist = [] - if self.name is not None: nodelist.append(self.name) - if self.subscript is not None: nodelist.append(self.subscript) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'ArrayRef: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class While(Node): - def __init__(self, cond, stmt, coord=None): - self.cond = cond - self.stmt = stmt - self.coord = coord - - def children(self): - nodelist = [] - if self.cond is not None: nodelist.append(self.cond) - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'While: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class EnumeratorList(Node): - def __init__(self, enumerators, coord=None): - self.enumerators = enumerators - self.coord = coord - - def children(self): - nodelist = [] - if self.enumerators is not None: nodelist.extend(self.enumerators) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'EnumeratorList: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class EllipsisParam(Node): - def __init__(self, coord=None): - self.coord = coord - - def children(self): - return () - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'EllipsisParam: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class If(Node): - def __init__(self, cond, iftrue, iffalse, coord=None): - self.cond = cond - self.iftrue = iftrue - self.iffalse = iffalse - self.coord = coord - - def children(self): - nodelist = [] - if self.cond is not None: nodelist.append(self.cond) - if self.iftrue is not None: nodelist.append(self.iftrue) - if self.iffalse is not None: nodelist.append(self.iffalse) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'If: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - diff --git a/plugins_available/pycparser/pycparser/c_lexer.py b/plugins_available/pycparser/pycparser/c_lexer.py deleted file mode 100644 index 28638df..0000000 --- a/plugins_available/pycparser/pycparser/c_lexer.py +++ /dev/null @@ -1,443 +0,0 @@ -#----------------------------------------------------------------- -# pycparser: clex.py -# -# CLexer class: lexer for the C language -# -# Copyright (C) 2008, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - -import re -import sys - -import ply.lex -from ply.lex import TOKEN - - -class CLexer(object): - """ A lexer for the C language. After building it, set the - input text with input(), and call token() to get new - tokens. - - The public attribute filename can be set to an initial - filaneme, but the lexer will update it upon #line - directives. - """ - def __init__(self, error_func, type_lookup_func): - """ Create a new Lexer. - - error_func: - An error function. Will be called with an error - message, line and column as arguments, in case of - an error during lexing. - - type_lookup_func: - A type lookup function. Given a string, it must - return True IFF this string is a name of a type - that was defined with a typedef earlier. - """ - self.error_func = error_func - self.type_lookup_func = type_lookup_func - self.filename = '' - - # Allow either "# line" or "# " to support GCC's - # cpp output - # - self.line_pattern = re.compile('([ \t]*line\W)|([ \t]*\d+)') - - def build(self, **kwargs): - """ Builds the lexer from the specification. Must be - called after the lexer object is created. - - This method exists separately, because the PLY - manual warns against calling lex.lex inside - __init__ - """ - self.lexer = ply.lex.lex(object=self, **kwargs) - - def reset_lineno(self): - """ Resets the internal line number counter of the lexer. - """ - self.lexer.lineno = 1 - - def input(self, text): - self.lexer.input(text) - - def token(self): - g = self.lexer.token() - return g - - ######################-- PRIVATE --###################### - - ## - ## Internal auxiliary methods - ## - def _error(self, msg, token): - location = self._make_tok_location(token) - self.error_func(msg, location[0], location[1]) - self.lexer.skip(1) - - def _find_tok_column(self, token): - i = token.lexpos - while i > 0: - if self.lexer.lexdata[i] == '\n': break - i -= 1 - return (token.lexpos - i) + 1 - - def _make_tok_location(self, token): - return (token.lineno, self._find_tok_column(token)) - - ## - ## Reserved keywords - ## - keywords = ( - 'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST', 'CONTINUE', - 'DEFAULT', 'DO', 'DOUBLE', 'ELSE', 'ENUM', 'EXTERN', - 'FLOAT', 'FOR', 'GOTO', 'IF', 'INT', 'LONG', 'REGISTER', - 'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT', - 'SWITCH', 'TYPEDEF', 'UNION', 'UNSIGNED', 'VOID', - 'VOLATILE', 'WHILE', - ) - - keyword_map = {} - for r in keywords: - keyword_map[r.lower()] = r - - ## - ## All the tokens recognized by the lexer - ## - tokens = keywords + ( - # Identifiers - 'ID', - - # Type identifiers (identifiers previously defined as - # types with typedef) - 'TYPEID', - - # constants - 'INT_CONST_DEC', 'INT_CONST_OCT', 'INT_CONST_HEX', - 'FLOAT_CONST', - 'CHAR_CONST', - 'WCHAR_CONST', - - # String literals - 'STRING_LITERAL', - 'WSTRING_LITERAL', - - # Operators - 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD', - 'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT', - 'LOR', 'LAND', 'LNOT', - 'LT', 'LE', 'GT', 'GE', 'EQ', 'NE', - - # Assignment - 'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL', - 'PLUSEQUAL', 'MINUSEQUAL', - 'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL', - 'OREQUAL', - - # Increment/decrement - 'PLUSPLUS', 'MINUSMINUS', - - # Structure dereference (->) - 'ARROW', - - # Conditional operator (?) - 'CONDOP', - - # Delimeters - 'LPAREN', 'RPAREN', # ( ) - 'LBRACKET', 'RBRACKET', # [ ] - 'LBRACE', 'RBRACE', # { } - 'COMMA', 'PERIOD', # . , - 'SEMI', 'COLON', # ; : - - # Ellipsis (...) - 'ELLIPSIS', - - # pre-processor - 'PPHASH', # '#' - ) - - ## - ## Regexes for use in tokens - ## - ## - - # valid C identifiers (K&R2: A.2.3) - identifier = r'[a-zA-Z_][0-9a-zA-Z_]*' - - # integer constants (K&R2: A.2.5.1) - integer_suffix_opt = r'(([uU][lL])|([lL][uU])|[uU]|[lL])?' - decimal_constant = '(0'+integer_suffix_opt+')|([1-9][0-9]*'+integer_suffix_opt+')' - octal_constant = '0[0-7]*'+integer_suffix_opt - hex_constant = '0[xX][0-9a-fA-F]+'+integer_suffix_opt - - bad_octal_constant = '0[0-7]*[89]' - - # character constants (K&R2: A.2.5.2) - # Note: a-zA-Z are allowed as escape chars to support #line - # directives with Windows paths as filenames (\dir\file...) - # - simple_escape = r"""([a-zA-Z\\?'"])""" - octal_escape = r"""([0-7]{1,3})""" - hex_escape = r"""(x[0-9a-fA-F]+)""" - bad_escape = r"""([\\][^a-zA-Z\\?'"x0-7])""" - - escape_sequence = r"""(\\("""+simple_escape+'|'+octal_escape+'|'+hex_escape+'))' - cconst_char = r"""([^'\\\n]|"""+escape_sequence+')' - char_const = "'"+cconst_char+"'" - wchar_const = 'L'+char_const - unmatched_quote = "('"+cconst_char+"*\\n)|('"+cconst_char+"*$)" - bad_char_const = r"""('"""+cconst_char+"""[^'\n]+')|('')|('"""+bad_escape+r"""[^'\n]*')""" - - # string literals (K&R2: A.2.6) - string_char = r"""([^"\\\n]|"""+escape_sequence+')' - string_literal = '"'+string_char+'*"' - wstring_literal = 'L'+string_literal - bad_string_literal = '"'+string_char+'*'+bad_escape+string_char+'*"' - - # floating constants (K&R2: A.2.5.3) - exponent_part = r"""([eE][-+]?[0-9]+)""" - fractional_constant = r"""([0-9]*\.[0-9]+)|([0-9]+\.)""" - floating_constant = '(((('+fractional_constant+')'+exponent_part+'?)|([0-9]+'+exponent_part+'))[FfLl]?)' - - ## - ## Lexer states - ## - states = ( - # ppline: preprocessor line directives - # - ('ppline', 'exclusive'), - ) - - def t_PPHASH(self, t): - r'[ \t]*\#' - m = self.line_pattern.match( - t.lexer.lexdata, pos=t.lexer.lexpos) - - if m: - t.lexer.begin('ppline') - self.pp_line = self.pp_filename = None - #~ print "ppline starts on line %s" % t.lexer.lineno - else: - t.type = 'PPHASH' - return t - - ## - ## Rules for the ppline state - ## - @TOKEN(string_literal) - def t_ppline_FILENAME(self, t): - if self.pp_line is None: - self._error('filename before line number in #line', t) - else: - self.pp_filename = t.value.lstrip('"').rstrip('"') - #~ print "PP got filename: ", self.pp_filename - - @TOKEN(decimal_constant) - def t_ppline_LINE_NUMBER(self, t): - if self.pp_line is None: - self.pp_line = t.value - else: - # Ignore: GCC's cpp sometimes inserts a numeric flag - # after the file name - pass - - def t_ppline_NEWLINE(self, t): - r'\n' - - if self.pp_line is None: - self._error('line number missing in #line', t) - else: - self.lexer.lineno = int(self.pp_line) - - if self.pp_filename is not None: - self.filename = self.pp_filename - - t.lexer.begin('INITIAL') - - def t_ppline_PPLINE(self, t): - r'line' - pass - - t_ppline_ignore = ' \t' - - def t_ppline_error(self, t): - msg = 'invalid #line directive' - self._error(msg, t) - - ## - ## Rules for the normal state - ## - t_ignore = ' \t' - - # Newlines - def t_NEWLINE(self, t): - r'\n+' - t.lexer.lineno += t.value.count("\n") - - # Operators - t_PLUS = r'\+' - t_MINUS = r'-' - t_TIMES = r'\*' - t_DIVIDE = r'/' - t_MOD = r'%' - t_OR = r'\|' - t_AND = r'&' - t_NOT = r'~' - t_XOR = r'\^' - t_LSHIFT = r'<<' - t_RSHIFT = r'>>' - t_LOR = r'\|\|' - t_LAND = r'&&' - t_LNOT = r'!' - t_LT = r'<' - t_GT = r'>' - t_LE = r'<=' - t_GE = r'>=' - t_EQ = r'==' - t_NE = r'!=' - - # Assignment operators - t_EQUALS = r'=' - t_TIMESEQUAL = r'\*=' - t_DIVEQUAL = r'/=' - t_MODEQUAL = r'%=' - t_PLUSEQUAL = r'\+=' - t_MINUSEQUAL = r'-=' - t_LSHIFTEQUAL = r'<<=' - t_RSHIFTEQUAL = r'>>=' - t_ANDEQUAL = r'&=' - t_OREQUAL = r'\|=' - t_XOREQUAL = r'^=' - - # Increment/decrement - t_PLUSPLUS = r'\+\+' - t_MINUSMINUS = r'--' - - # -> - t_ARROW = r'->' - - # ? - t_CONDOP = r'\?' - - # Delimeters - t_LPAREN = r'\(' - t_RPAREN = r'\)' - t_LBRACKET = r'\[' - t_RBRACKET = r'\]' - t_LBRACE = r'\{' - t_RBRACE = r'\}' - t_COMMA = r',' - t_PERIOD = r'\.' - t_SEMI = r';' - t_COLON = r':' - t_ELLIPSIS = r'\.\.\.' - - t_STRING_LITERAL = string_literal - - # The following floating and integer constants are defined as - # functions to impose a strict order (otherwise, decimal - # is placed before the others because its regex is longer, - # and this is bad) - # - @TOKEN(floating_constant) - def t_FLOAT_CONST(self, t): - return t - - @TOKEN(hex_constant) - def t_INT_CONST_HEX(self, t): - return t - - @TOKEN(bad_octal_constant) - def t_BAD_CONST_OCT(self, t): - msg = "Invalid octal constant" - self._error(msg, t) - - @TOKEN(octal_constant) - def t_INT_CONST_OCT(self, t): - return t - - @TOKEN(decimal_constant) - def t_INT_CONST_DEC(self, t): - return t - - # Must come before bad_char_const, to prevent it from - # catching valid char constants as invalid - # - @TOKEN(char_const) - def t_CHAR_CONST(self, t): - return t - - @TOKEN(wchar_const) - def t_WCHAR_CONST(self, t): - return t - - @TOKEN(unmatched_quote) - def t_UNMATCHED_QUOTE(self, t): - msg = "Unmatched '" - self._error(msg, t) - - @TOKEN(bad_char_const) - def t_BAD_CHAR_CONST(self, t): - msg = "Invalid char constant %s" % t.value - self._error(msg, t) - - @TOKEN(wstring_literal) - def t_WSTRING_LITERAL(self, t): - return t - - # unmatched string literals are caught by the preprocessor - - @TOKEN(bad_string_literal) - def t_BAD_STRING_LITERAL(self, t): - msg = "String contains invalid escape code" - self._error(msg, t) - - @TOKEN(identifier) - def t_ID(self, t): - t.type = self.keyword_map.get(t.value, "ID") - - if t.type == 'ID' and self.type_lookup_func(t.value): - t.type = "TYPEID" - - return t - - def t_error(self, t): - msg = 'Illegal character %s' % repr(t.value[0]) - self._error(msg, t) - - -if __name__ == "__main__": - filename = '../zp.c' - text = open(filename).read() - - #~ text = '"'+r"""ka \p ka"""+'"' - text = r""" - 546 - #line 66 "kwas\df.h" - id 4 - # 5 - dsf - """ - - def errfoo(msg, a, b): - print msg - sys.exit() - - def typelookup(namd): - return False - - clex = CLexer(errfoo, typelookup) - clex.build() - clex.input(text) - - while 1: - tok = clex.token() - if not tok: break - - #~ print type(tok) - print "-", tok.value, tok.type, tok.lineno, clex.filename, tok.lexpos - - diff --git a/plugins_available/pycparser/pycparser/c_parser.py b/plugins_available/pycparser/pycparser/c_parser.py deleted file mode 100644 index 6c03660..0000000 --- a/plugins_available/pycparser/pycparser/c_parser.py +++ /dev/null @@ -1,1259 +0,0 @@ -#----------------------------------------------------------------- -# pycparser: cparse.py -# -# CParser class: Parser and AST builder for the C language -# -# Copyright (C) 2008, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - -import re -import sys -from types import StringType - -import ply.yacc - -import c_ast -from c_lexer import CLexer -from plyparser import PLYParser, Coord, ParseError - - -class CParser(PLYParser): - def __init__( - self, - lex_optimize=True, - lextab='pycparser.lextab', - yacc_optimize=True, - yacctab='pycparser.yacctab', - yacc_debug=False): - """ Create a new CParser. - - Some arguments for controlling the debug/optimization - level of the parser are provided. The defaults are - tuned for release/performance mode. - The simple rules for using them are: - *) When tweaking CParser/CLexer, set these to False - *) When releasing a stable parser, set to True - - lex_optimize: - Set to False when you're modifying the lexer. - Otherwise, changes in the lexer won't be used, if - some lextab.py file exists. - When releasing with a stable lexer, set to True - to save the re-generation of the lexer table on - each run. - - lextab: - Points to the lex table that's used for optimized - mode. Only if you're modifying the lexer and want - some tests to avoid re-generating the table, make - this point to a local lex table file (that's been - earlier generated with lex_optimize=True) - - yacc_optimize: - Set to False when you're modifying the parser. - Otherwise, changes in the parser won't be used, if - some parsetab.py file exists. - When releasing with a stable parser, set to True - to save the re-generation of the parser table on - each run. - - yacctab: - Points to the yacc table that's used for optimized - mode. Only if you're modifying the parser, make - this point to a local yacc table file - - yacc_debug: - Generate a parser.out file that explains how yacc - built the parsing table from the grammar. - """ - self.clex = CLexer( - error_func=self._lex_error_func, - type_lookup_func=self._lex_type_lookup_func) - - self.clex.build( - optimize=lex_optimize, - lextab=lextab) - self.tokens = self.clex.tokens - - rules_with_opt = [ - 'abstract_declarator', - 'constant_expression', - 'declaration_list', - 'declaration_specifiers', - 'expression', - 'identifier_list', - 'init_declarator_list', - 'parameter_type_list', - 'specifier_qualifier_list', - 'statement_list', - 'type_qualifier_list', - ] - - for rule in rules_with_opt: - self._create_opt_rule(rule) - - self.cparser = ply.yacc.yacc( - module=self, - start='translation_unit', - debug=yacc_debug, - optimize=yacc_optimize, - tabmodule=yacctab) - - # A table of identifiers defined as typedef types during - # parsing. - # - self.typedef_table = set([]) - - def parse(self, text, filename='', debuglevel=0): - """ Parses C code and returns an AST. - - text: - A string containing the C source code - - filename: - Name of the file being parsed (for meaningful - error messages) - - debuglevel: - Debug level to yacc - """ - self.clex.filename = filename - self.clex.reset_lineno() - self.typedef_table = set([]) - return self.cparser.parse(text, lexer=self.clex, debug=debuglevel) - - ######################-- PRIVATE --###################### - - def _lex_error_func(self, msg, line, column): - self._parse_error(msg, self._coord(line, column)) - - def _lex_type_lookup_func(self, name): - """ Looks up types that were previously defined with - typedef. - Passed to the lexer for recognizing identifiers that - are types. - """ - return name in self.typedef_table - - def _add_typedef_type(self, name): - """ Adds names that were defined as new types with - typedef. - """ - self.typedef_table.add(name) - - # To understand what's going on here, read sections A.8.5 and - # A.8.6 of K&R2 very carefully. - # - # A C type consists of a basic type declaration, with a list - # of modifiers. For example: - # - # int *c[5]; - # - # The basic declaration here is 'int x', and the pointer and - # the array are the modifiers. - # - # Basic declarations are represented by TypeDecl (from module - # c_ast) and the modifiers are FuncDecl, PtrDecl and - # ArrayDecl. - # - # The standard states that whenever a new modifier is parsed, - # it should be added to the end of the list of modifiers. For - # example: - # - # K&R2 A.8.6.2: Array Declarators - # - # In a declaration T D where D has the form - # D1 [constant-expression-opt] - # and the type of the identifier in the declaration T D1 is - # "type-modifier T", the type of the - # identifier of D is "type-modifier array of T" - # - # This is what this method does. The declarator it receives - # can be a list of declarators ending with TypeDecl. It - # tacks the modifier to the end of this list, just before - # the TypeDecl. - # - # Additionally, the modifier may be a list itself. This is - # useful for pointers, that can come as a chain from the rule - # p_pointer. In this case, the whole modifier list is spliced - # into the new location. - # - def _type_modify_decl(self, decl, modifier): - """ Tacks a type modifier on a declarator, and returns - the modified declarator. - - Note: the declarator and modifier may be modified - """ - #~ print '****' - #~ decl.show(offset=3) - #~ modifier.show(offset=3) - #~ print '****' - - modifier_head = modifier - modifier_tail = modifier - - # The modifier may be a nested list. Reach its tail. - # - while modifier_tail.type: - modifier_tail = modifier_tail.type - - # If the decl is a basic type, just tack the modifier onto - # it - # - if isinstance(decl, c_ast.TypeDecl): - modifier_tail.type = decl - return modifier - else: - # Otherwise, the decl is a list of modifiers. Reach - # its tail and splice the modifier onto the tail, - # pointing to the underlying basic type. - # - decl_tail = decl - - while not isinstance(decl_tail.type, c_ast.TypeDecl): - decl_tail = decl_tail.type - - modifier_tail.type = decl_tail.type - decl_tail.type = modifier_head - return decl - - # Due to the order in which declarators are constructed, - # they have to be fixed in order to look like a normal AST. - # - # When a declaration arrives from syntax construction, it has - # these problems: - # * The innermost TypeDecl has no type (because the basic - # type is only known at the uppermost declaration level) - # * The declaration has no variable name, since that is saved - # in the innermost TypeDecl - # * The typename of the declaration is a list of type - # specifiers, and not a node. Here, basic identifier types - # should be separated from more complex types like enums - # and structs. - # - # This method fixes these problem. - # - def _fix_decl_name_type(self, decl, typename): - """ Fixes a declaration. Modifies decl. - """ - # Reach the underlying basic type - # - type = decl - while not isinstance(type, c_ast.TypeDecl): - type = type.type - - decl.name = type.declname - type.quals = decl.quals - - # The typename is a list of types. If any type in this - # list isn't a simple string type, it must be the only - # type in the list (it's illegal to declare "int enum .." - # If all the types are basic, they're collected in the - # IdentifierType holder. - # - for tn in typename: - if not isinstance(tn, StringType): - if len(typename) > 1: - self._parse_error( - "Invalid multiple types specified", tn.coord) - else: - type.type = tn - return decl - - type.type = c_ast.IdentifierType(typename) - return decl - - def _add_declaration_specifier(self, declspec, newspec, kind): - """ Declaration specifiers are represented by a dictionary - with 3 entries: - * qual: a list of type qualifiers - * storage: a list of storage type qualifiers - * type: a list of type specifiers - - This method is given a declaration specifier, and a - new specifier of a given kind. - Returns the declaration specifier, with the new - specifier incorporated. - """ - spec = declspec or dict(qual=[], storage=[], type=[]) - spec[kind].append(newspec) - return spec - - def _build_function_definition(self, decl, spec, param_decls, body): - """ Builds a function definition. - """ - declaration = c_ast.Decl( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=decl, - init=None, - bitsize=None, - coord=decl.coord) - - typename = spec['type'] - declaration = self._fix_decl_name_type(declaration, typename) - return c_ast.FuncDef( - decl=declaration, - param_decls=param_decls, - body=body, - coord=decl.coord) - - def _select_struct_union_class(self, token): - """ Given a token (either STRUCT or UNION), selects the - appropriate AST class. - """ - if token == 'struct': - return c_ast.Struct - else: - return c_ast.Union - - ## - ## Precedence and associativity of operators - ## - precedence = ( - ('left', 'LOR'), - ('left', 'LAND'), - ('left', 'OR'), - ('left', 'XOR'), - ('left', 'AND'), - ('left', 'EQ', 'NE'), - ('left', 'GT', 'GE', 'LT', 'LE'), - ('left', 'RSHIFT', 'LSHIFT'), - ('left', 'PLUS', 'MINUS'), - ('left', 'TIMES', 'DIVIDE', 'MOD') - ) - - ## - ## Grammar productions - ## Implementation of the BNF defined in K&R2 A.13 - ## - def p_translation_unit_1(self, p): - """ translation_unit : external_declaration - """ - # Note: external_declaration is already a list - # - p[0] = c_ast.FileAST(p[1]) - - def p_translation_unit_2(self, p): - """ translation_unit : translation_unit external_declaration - """ - p[1].ext.extend(p[2]) - p[0] = p[1] - - # Declarations always come as lists (because they can be - # several in one line), so we wrap the function definition - # into a list as well, to make the return value of - # external_declaration homogenous. - # - def p_external_declaration_1(self, p): - """ external_declaration : function_definition - """ - p[0] = [p[1]] - - def p_external_declaration_2(self, p): - """ external_declaration : declaration - """ - p[0] = p[1] - - def p_external_declaration_3(self, p): - """ external_declaration : pp_directive - """ - p[0] = p[1] - - def p_pp_directive(self, p): - """ pp_directive : PPHASH - """ - self._parse_error('Directives not supported yet', - self._coord(p.lineno(1))) - - # In function definitions, the declarator can be followed by - # a declaration list, for old "K&R style" function definitios. - # - def p_function_definition_1(self, p): - """ function_definition : declarator declaration_list_opt compound_statement - """ - # no declaration specifiers - spec = dict(qual=[], storage=[], type=[]) - - p[0] = self._build_function_definition( - decl=p[1], - spec=spec, - param_decls=p[2], - body=p[3]) - - def p_function_definition_2(self, p): - """ function_definition : declaration_specifiers declarator declaration_list_opt compound_statement - """ - spec = p[1] - - p[0] = self._build_function_definition( - decl=p[2], - spec=spec, - param_decls=p[3], - body=p[4]) - - def p_statement(self, p): - """ statement : labeled_statement - | expression_statement - | compound_statement - | selection_statement - | iteration_statement - | jump_statement - """ - p[0] = p[1] - - # In C, declarations can come several in a line: - # int x, *px, romulo = 5; - # - # However, for the AST, we will split them to separate Decl - # nodes. - # - # This rule splits its declarations and always returns a list - # of Decl nodes, even if it's one element long. - # - def p_decl_body(self, p): - """ decl_body : declaration_specifiers init_declarator_list_opt - """ - spec = p[1] - is_typedef = 'typedef' in spec['storage'] - decls = [] - - # p[2] (init_declarator_list_opt) is either a list or None - # - if p[2] is None: - # Then it's a declaration of a struct / enum tag, - # without an actual declarator. - # - type = spec['type'] - if len(type) > 1: - coord = '?' - for t in type: - if hasattr(t, 'coord'): - coord = t.coord - break - - self._parse_error('Multiple type specifiers with a type tag', coord) - - decl = c_ast.Decl( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=type[0], - init=None, - bitsize=None, - coord=type[0].coord) - decls = [decl] - else: - for decl, init in p[2] or []: - if is_typedef: - decl = c_ast.Typedef( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=decl, - coord=decl.coord) - else: - decl = c_ast.Decl( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=decl, - init=init, - bitsize=None, - coord=decl.coord) - - typename = spec['type'] - fixed_decl = self._fix_decl_name_type(decl, typename) - - # Add the type name defined by typedef to a - # symbol table (for usage in the lexer) - # - if is_typedef: - self._add_typedef_type(fixed_decl.name) - - decls.append(fixed_decl) - - p[0] = decls - - # The declaration has been split to a decl_body sub-rule and - # SEMI, because having them in a single rule created a problem - # for defining typedefs. - # - # If a typedef line was directly followed by a line using the - # type defined with the typedef, the type would not be - # recognized. This is because to reduce the declaration rule, - # the parser's lookahead asked for the token after SEMI, which - # was the type from the next line, and the lexer had no chance - # to see the updated type symbol table. - # - # Splitting solves this problem, because after seeing SEMI, - # the parser reduces decl_body, which actually adds the new - # type into the table to be seen by the lexer before the next - # line is reached. - # - def p_declaration(self, p): - """ declaration : decl_body SEMI - """ - p[0] = p[1] - - # Since each declaration is a list of declarations, this - # rule will combine all the declarations and return a single - # list - # - def p_declaration_list(self, p): - """ declaration_list : declaration - | declaration_list declaration - """ - p[0] = p[1] if len(p) == 2 else p[1] + p[2] - - def p_declaration_specifiers_1(self, p): - """ declaration_specifiers : type_qualifier declaration_specifiers_opt - """ - p[0] = self._add_declaration_specifier(p[2], p[1], 'qual') - - def p_declaration_specifiers_2(self, p): - """ declaration_specifiers : type_specifier declaration_specifiers_opt - """ - p[0] = self._add_declaration_specifier(p[2], p[1], 'type') - - def p_declaration_specifiers_3(self, p): - """ declaration_specifiers : storage_class_specifier declaration_specifiers_opt - """ - p[0] = self._add_declaration_specifier(p[2], p[1], 'storage') - - def p_storage_class_specifier(self, p): - """ storage_class_specifier : AUTO - | REGISTER - | STATIC - | EXTERN - | TYPEDEF - """ - p[0] = p[1] - - def p_type_specifier_1(self, p): - """ type_specifier : VOID - | CHAR - | SHORT - | INT - | LONG - | FLOAT - | DOUBLE - | SIGNED - | UNSIGNED - | typedef_name - | enum_specifier - | struct_or_union_specifier - """ - p[0] = p[1] - - def p_type_qualifier(self, p): - """ type_qualifier : CONST - | VOLATILE - """ - p[0] = p[1] - - def p_init_declarator_list(self, p): - """ init_declarator_list : init_declarator - | init_declarator_list COMMA init_declarator - """ - p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]] - - # Returns a (declarator, intializer) pair - # If there's no initializer, returns (declarator, None) - # - def p_init_declarator(self, p): - """ init_declarator : declarator - | declarator EQUALS initializer - """ - p[0] = (p[1], p[3] if len(p) > 2 else None) - - def p_specifier_qualifier_list_1(self, p): - """ specifier_qualifier_list : type_qualifier specifier_qualifier_list_opt - """ - p[0] = self._add_declaration_specifier(p[2], p[1], 'qual') - - def p_specifier_qualifier_list_2(self, p): - """ specifier_qualifier_list : type_specifier specifier_qualifier_list_opt - """ - p[0] = self._add_declaration_specifier(p[2], p[1], 'type') - - # TYPEID is allowed here (and in other struct/enum related tag names), because - # struct/enum tags reside in their own namespace and can be named the same as types - # - def p_struct_or_union_specifier_1(self, p): - """ struct_or_union_specifier : struct_or_union ID - | struct_or_union TYPEID - """ - klass = self._select_struct_union_class(p[1]) - p[0] = klass( - name=p[2], - decls=None, - coord=self._coord(p.lineno(2))) - - def p_struct_or_union_specifier_2(self, p): - """ struct_or_union_specifier : struct_or_union LBRACE struct_declaration_list RBRACE - """ - klass = self._select_struct_union_class(p[1]) - p[0] = klass( - name=None, - decls=p[3], - coord=self._coord(p.lineno(2))) - - def p_struct_or_union_specifier_3(self, p): - """ struct_or_union_specifier : struct_or_union ID LBRACE struct_declaration_list RBRACE - | struct_or_union TYPEID LBRACE struct_declaration_list RBRACE - """ - klass = self._select_struct_union_class(p[1]) - p[0] = klass( - name=p[2], - decls=p[4], - coord=self._coord(p.lineno(2))) - - def p_struct_or_union(self, p): - """ struct_or_union : STRUCT - | UNION - """ - p[0] = p[1] - - # Combine all declarations into a single list - # - def p_struct_declaration_list(self, p): - """ struct_declaration_list : struct_declaration - | struct_declaration_list struct_declaration - """ - p[0] = p[1] if len(p) == 2 else p[1] + p[2] - - def p_struct_declaration_1(self, p): - """ struct_declaration : specifier_qualifier_list struct_declarator_list SEMI - """ - spec = p[1] - decls = [] - - for struct_decl in p[2]: - decl = c_ast.Decl( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=struct_decl['decl'], - init=None, - bitsize=struct_decl['bitsize'], - coord=struct_decl['decl'].coord) - - typename = spec['type'] - decls.append(self._fix_decl_name_type(decl, typename)) - - p[0] = decls - - def p_struct_declarator_list(self, p): - """ struct_declarator_list : struct_declarator - | struct_declarator_list COMMA struct_declarator - """ - p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]] - - # struct_declarator passes up a dict with the keys: decl (for - # the underlying declarator) and bitsize (for the bitsize) - # - def p_struct_declarator_1(self, p): - """ struct_declarator : declarator - """ - p[0] = {'decl': p[1], 'bitsize': None} - - def p_struct_declarator_2(self, p): - """ struct_declarator : declarator COLON constant_expression - | COLON constant_expression - """ - if len(p) > 3: - p[0] = {'decl': p[1], 'bitsize': p[3]} - else: - p[0] = {'decl': None, 'bitsize': p[2]} - - def p_enum_specifier_1(self, p): - """ enum_specifier : ENUM ID - | ENUM TYPEID - """ - p[0] = c_ast.Enum(p[2], None, self._coord(p.lineno(1))) - - def p_enum_specifier_2(self, p): - """ enum_specifier : ENUM LBRACE enumerator_list RBRACE - """ - p[0] = c_ast.Enum(None, p[3], self._coord(p.lineno(1))) - - def p_enum_specifier_3(self, p): - """ enum_specifier : ENUM ID LBRACE enumerator_list RBRACE - | ENUM TYPEID LBRACE enumerator_list RBRACE - """ - p[0] = c_ast.Enum(p[2], p[4], self._coord(p.lineno(1))) - - def p_enumerator_list(self, p): - """ enumerator_list : enumerator - | enumerator_list COMMA - | enumerator_list COMMA enumerator - """ - if len(p) == 2: - p[0] = c_ast.EnumeratorList([p[1]], p[1].coord) - elif len(p) == 3: - p[0] = p[1] - else: - p[1].enumerators.append(p[3]) - p[0] = p[1] - - def p_enumerator(self, p): - """ enumerator : ID - | ID EQUALS constant_expression - """ - if len(p) == 2: - p[0] = c_ast.Enumerator( - p[1], None, - self._coord(p.lineno(1))) - else: - p[0] = c_ast.Enumerator( - p[1], p[3], - self._coord(p.lineno(1))) - - def p_declarator_1(self, p): - """ declarator : direct_declarator - """ - p[0] = p[1] - - def p_declarator_2(self, p): - """ declarator : pointer direct_declarator - """ - p[0] = self._type_modify_decl(p[2], p[1]) - - def p_direct_declarator_1(self, p): - """ direct_declarator : ID - """ - p[0] = c_ast.TypeDecl( - declname=p[1], - type=None, - quals=None, - coord=self._coord(p.lineno(1))) - - def p_direct_declarator_2(self, p): - """ direct_declarator : LPAREN declarator RPAREN - """ - p[0] = p[2] - - def p_direct_declarator_3(self, p): - """ direct_declarator : direct_declarator LBRACKET constant_expression_opt RBRACKET - """ - arr = c_ast.ArrayDecl( - type=None, - dim=p[3], - coord=p[1].coord) - - p[0] = self._type_modify_decl(decl=p[1], modifier=arr) - - def p_direct_declarator_4(self, p): - """ direct_declarator : direct_declarator LPAREN parameter_type_list RPAREN - | direct_declarator LPAREN identifier_list_opt RPAREN - """ - func = c_ast.FuncDecl( - args=p[3], - type=None, - coord=p[1].coord) - - p[0] = self._type_modify_decl(decl=p[1], modifier=func) - - def p_pointer(self, p): - """ pointer : TIMES type_qualifier_list_opt - | TIMES type_qualifier_list_opt pointer - """ - coord = self._coord(p.lineno(1)) - - p[0] = c_ast.PtrDecl( - quals=p[2] or [], - type=p[3] if len(p) > 3 else None, - coord=coord) - - def p_type_qualifier_list(self, p): - """ type_qualifier_list : type_qualifier - | type_qualifier_list type_qualifier - """ - p[0] = [p[1]] if len(p) == 2 else p[1] + [p[2]] - - def p_parameter_type_list(self, p): - """ parameter_type_list : parameter_list - | parameter_list COMMA ELLIPSIS - """ - if len(p) > 2: - p[1].params.append(c_ast.EllipsisParam()) - - p[0] = p[1] - - def p_parameter_list(self, p): - """ parameter_list : parameter_declaration - | parameter_list COMMA parameter_declaration - """ - if len(p) == 2: # single parameter - p[0] = c_ast.ParamList([p[1]], p[1].coord) - else: - p[1].params.append(p[3]) - p[0] = p[1] - - def p_parameter_declaration_1(self, p): - """ parameter_declaration : declaration_specifiers declarator - """ - spec = p[1] - decl = p[2] - - decl = c_ast.Decl( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=decl, - init=None, - bitsize=None, - coord=decl.coord) - - typename = spec['type'] or ['int'] - p[0] = self._fix_decl_name_type(decl, typename) - - def p_parameter_declaration_2(self, p): - """ parameter_declaration : declaration_specifiers abstract_declarator_opt - """ - spec = p[1] - decl = c_ast.Typename( - quals=spec['qual'], - type=p[2] or c_ast.TypeDecl(None, None, None)) - - typename = spec['type'] or ['int'] - - p[0] = self._fix_decl_name_type(decl, typename) - - def p_identifier_list(self, p): - """ identifier_list : identifier - | identifier_list COMMA identifier - """ - if len(p) == 2: # single parameter - p[0] = c_ast.ParamList([p[1]], p[1].coord) - else: - p[1].params.append(p[3]) - p[0] = p[1] - - def p_initializer_1(self, p): - """ initializer : assignment_expression - """ - p[0] = p[1] - - def p_initializer_2(self, p): - """ initializer : LBRACE initializer_list RBRACE - | LBRACE initializer_list COMMA RBRACE - """ - p[0] = p[2] - - def p_initializer_list(self, p): - """ initializer_list : initializer - | initializer_list COMMA initializer - """ - if len(p) == 2: # single initializer - p[0] = c_ast.ExprList([p[1]], p[1].coord) - else: - p[1].exprs.append(p[3]) - p[0] = p[1] - - def p_type_name(self, p): - """ type_name : specifier_qualifier_list abstract_declarator_opt - """ - #~ print '==========' - #~ print p[1] - #~ print p[2] - #~ print p[2].children() - #~ print '==========' - - typename = c_ast.Typename( - quals=p[1]['qual'], - type=p[2] or c_ast.TypeDecl(None, None, None)) - - p[0] = self._fix_decl_name_type(typename, p[1]['type']) - - def p_abstract_declarator_1(self, p): - """ abstract_declarator : pointer - """ - dummytype = c_ast.TypeDecl(None, None, None) - p[0] = self._type_modify_decl( - decl=dummytype, - modifier=p[1]) - - def p_abstract_declarator_2(self, p): - """ abstract_declarator : pointer direct_abstract_declarator - """ - p[0] = self._type_modify_decl(p[2], p[1]) - - def p_abstract_declarator_3(self, p): - """ abstract_declarator : direct_abstract_declarator - """ - p[0] = p[1] - - # Creating and using direct_abstract_declarator_opt here - # instead of listing both direct_abstract_declarator and the - # lack of it in the beginning of _1 and _2 caused two - # shift/reduce errors. - # - def p_direct_abstract_declarator_1(self, p): - """ direct_abstract_declarator : LPAREN abstract_declarator RPAREN """ - p[0] = p[2] - - def p_direct_abstract_declarator_2(self, p): - """ direct_abstract_declarator : direct_abstract_declarator LBRACKET constant_expression_opt RBRACKET - """ - arr = c_ast.ArrayDecl( - type=None, - dim=p[3], - coord=p[1].coord) - - p[0] = self._type_modify_decl(decl=p[1], modifier=arr) - - def p_direct_abstract_declarator_3(self, p): - """ direct_abstract_declarator : LBRACKET constant_expression_opt RBRACKET - """ - p[0] = c_ast.ArrayDecl( - type=c_ast.TypeDecl(None, None, None), - dim=p[2], - coord=self._coord(p.lineno(1))) - - def p_direct_abstract_declarator_4(self, p): - """ direct_abstract_declarator : direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN - """ - func = c_ast.FuncDecl( - args=p[3], - type=None, - coord=p[1].coord) - - p[0] = self._type_modify_decl(decl=p[1], modifier=func) - - def p_direct_abstract_declarator_5(self, p): - """ direct_abstract_declarator : LPAREN parameter_type_list_opt RPAREN - """ - p[0] = c_ast.FuncDecl( - args=p[2], - type=c_ast.TypeDecl(None, None, None), - coord=p[1].coord) - - def p_compound_statement_1(self, p): - """ compound_statement : LBRACE statement_list_opt RBRACE """ - p[0] = c_ast.Compound( - decls=None, - stmts=p[2], - coord=self._coord(p.lineno(1))) - - def p_compound_statement_2(self, p): - """ compound_statement : LBRACE declaration_list RBRACE """ - p[0] = c_ast.Compound( - decls=p[2], - stmts=None, - coord=self._coord(p.lineno(1))) - - def p_compound_statement_3(self, p): - """ compound_statement : LBRACE declaration_list statement_list RBRACE """ - #~ print '((((((' - #~ print p[2] - #~ print p[3] - #~ print '((((((' - p[0] = c_ast.Compound( - decls=p[2], - stmts=p[3], - coord=self._coord(p.lineno(1))) - - # Note: this doesn't create an AST node, but a list of AST - # nodes that will be used as the statement list of a compound - # - def p_statement_list(self, p): - """ statement_list : statement - | statement_list statement - """ - if len(p) == 2: # single expr - p[0] = [p[1]] if p[1] else [] - else: - p[0] = p[1] + ([p[2]] if p[2] else []) - - def p_labeled_statement_1(self, p): - """ labeled_statement : ID COLON statement """ - p[0] = c_ast.Label(p[1], p[3], self._coord(p.lineno(1))) - - def p_labeled_statement_2(self, p): - """ labeled_statement : CASE constant_expression COLON statement """ - p[0] = c_ast.Case(p[2], p[4], self._coord(p.lineno(1))) - - def p_labeled_statement_3(self, p): - """ labeled_statement : DEFAULT COLON statement """ - p[0] = c_ast.Default(p[3], self._coord(p.lineno(1))) - - def p_selection_statement_1(self, p): - """ selection_statement : IF LPAREN expression RPAREN statement """ - p[0] = c_ast.If(p[3], p[5], None, self._coord(p.lineno(1))) - - def p_selection_statement_2(self, p): - """ selection_statement : IF LPAREN expression RPAREN statement ELSE statement """ - p[0] = c_ast.If(p[3], p[5], p[7], self._coord(p.lineno(1))) - - def p_selection_statement_3(self, p): - """ selection_statement : SWITCH LPAREN expression RPAREN statement """ - p[0] = c_ast.Switch(p[3], p[5], self._coord(p.lineno(1))) - - def p_iteration_statement_1(self, p): - """ iteration_statement : WHILE LPAREN expression RPAREN statement """ - p[0] = c_ast.While(p[3], p[5], self._coord(p.lineno(1))) - - def p_iteration_statement_2(self, p): - """ iteration_statement : DO statement WHILE LPAREN expression RPAREN """ - p[0] = c_ast.DoWhile(p[5], p[2], self._coord(p.lineno(1))) - - def p_iteration_statement_3(self, p): - """ iteration_statement : FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN statement """ - p[0] = c_ast.For(p[3], p[5], p[7], p[9], self._coord(p.lineno(1))) - - def p_jump_statement_1(self, p): - """ jump_statement : GOTO ID SEMI """ - p[0] = c_ast.Goto(p[2], self._coord(p.lineno(1))) - - def p_jump_statement_2(self, p): - """ jump_statement : BREAK SEMI """ - p[0] = c_ast.Break(self._coord(p.lineno(1))) - - def p_jump_statement_3(self, p): - """ jump_statement : CONTINUE SEMI """ - p[0] = c_ast.Continue(self._coord(p.lineno(1))) - - def p_jump_statement_4(self, p): - """ jump_statement : RETURN expression SEMI - | RETURN SEMI - """ - p[0] = c_ast.Return(p[2] if len(p) == 4 else None, self._coord(p.lineno(1))) - - def p_expression_statement(self, p): - """ expression_statement : expression_opt SEMI """ - p[0] = p[1] - - def p_expression(self, p): - """ expression : assignment_expression - | expression COMMA assignment_expression - """ - if len(p) == 2: - p[0] = p[1] - else: - if not isinstance(p[1], c_ast.ExprList): - p[1] = c_ast.ExprList([p[1]], p[1].coord) - - p[1].exprs.append(p[3]) - p[0] = p[1] - - def p_typedef_name(self, p): - """ typedef_name : TYPEID """ - p[0] = p[1] - - def p_assignment_expression(self, p): - """ assignment_expression : conditional_expression - | unary_expression assignment_operator assignment_expression - """ - if len(p) == 2: - p[0] = p[1] - else: - p[0] = c_ast.Assignment(p[2], p[1], p[3], p[1].coord) - - # K&R2 defines these as many separate rules, to encode - # precedence and associativity. Why work hard ? I'll just use - # the built in precedence/associativity specification feature - # of PLY. (see precedence declaration above) - # - def p_assignment_operator(self, p): - """ assignment_operator : EQUALS - | XOREQUAL - | TIMESEQUAL - | DIVEQUAL - | MODEQUAL - | PLUSEQUAL - | MINUSEQUAL - | LSHIFTEQUAL - | RSHIFTEQUAL - | ANDEQUAL - | OREQUAL - """ - p[0] = p[1] - - def p_constant_expression(self, p): - """ constant_expression : conditional_expression """ - p[0] = p[1] - - def p_conditional_expression(self, p): - """ conditional_expression : binary_expression - | binary_expression CONDOP expression COLON conditional_expression - """ - if len(p) == 2: - p[0] = p[1] - else: - p[0] = c_ast.TernaryOp(p[1], p[3], p[5], p[1].coord) - - def p_binary_expression(self, p): - """ binary_expression : cast_expression - | binary_expression TIMES binary_expression - | binary_expression DIVIDE binary_expression - | binary_expression MOD binary_expression - | binary_expression PLUS binary_expression - | binary_expression MINUS binary_expression - | binary_expression RSHIFT binary_expression - | binary_expression LSHIFT binary_expression - | binary_expression LT binary_expression - | binary_expression LE binary_expression - | binary_expression GE binary_expression - | binary_expression GT binary_expression - | binary_expression EQ binary_expression - | binary_expression NE binary_expression - | binary_expression AND binary_expression - | binary_expression OR binary_expression - | binary_expression XOR binary_expression - | binary_expression LAND binary_expression - | binary_expression LOR binary_expression - """ - if len(p) == 2: - p[0] = p[1] - else: - p[0] = c_ast.BinaryOp(p[2], p[1], p[3], p[1].coord) - - def p_cast_expression_1(self, p): - """ cast_expression : unary_expression """ - p[0] = p[1] - - def p_cast_expression_2(self, p): - """ cast_expression : LPAREN type_name RPAREN cast_expression """ - p[0] = c_ast.Cast(p[2], p[4], p[2].coord) - - def p_unary_expression_1(self, p): - """ unary_expression : postfix_expression """ - p[0] = p[1] - - def p_unary_expression_2(self, p): - """ unary_expression : PLUSPLUS unary_expression - | MINUSMINUS unary_expression - | unary_operator cast_expression - """ - p[0] = c_ast.UnaryOp(p[1], p[2], p[2].coord) - - def p_unary_expression_3(self, p): - """ unary_expression : SIZEOF unary_expression - | SIZEOF LPAREN type_name RPAREN - """ - p[0] = c_ast.UnaryOp( - p[1], - p[2] if len(p) == 3 else p[3], - self._coord(p.lineno(1))) - - def p_unary_operator(self, p): - """ unary_operator : AND - | TIMES - | PLUS - | MINUS - | NOT - | LNOT - """ - p[0] = p[1] - - def p_postfix_exptession_1(self, p): - """ postfix_expression : primary_expression """ - p[0] = p[1] - - def p_postfix_exptession_2(self, p): - """ postfix_expression : postfix_expression LBRACKET expression RBRACKET """ - p[0] = c_ast.ArrayRef(p[1], p[3], p[1].coord) - - def p_postfix_exptession_3(self, p): - """ postfix_expression : postfix_expression LPAREN argument_expression_list RPAREN - | postfix_expression LPAREN RPAREN - """ - p[0] = c_ast.FuncCall(p[1], p[3] if len(p) == 5 else None) - - def p_postfix_expression_4(self, p): - """ postfix_expression : postfix_expression PERIOD identifier - | postfix_expression ARROW identifier - """ - p[0] = c_ast.StructRef(p[1], p[2], p[3], p[1].coord) - - def p_postfix_expression_5(self, p): - """ postfix_expression : postfix_expression PLUSPLUS - | postfix_expression MINUSMINUS - """ - p[0] = c_ast.UnaryOp('p' + p[2], p[1], p[1].coord) - - def p_primary_expression_1(self, p): - """ primary_expression : identifier """ - p[0] = p[1] - - def p_primary_expression_2(self, p): - """ primary_expression : constant """ - p[0] = p[1] - - def p_primary_expression_3(self, p): - """ primary_expression : STRING_LITERAL - | WSTRING_LITERAL - """ - p[0] = c_ast.Constant( - 'string', p[1], self._coord(p.lineno(1))) - - def p_primary_expression_4(self, p): - """ primary_expression : LPAREN expression RPAREN """ - p[0] = p[2] - - def p_argument_expression_list(self, p): - """ argument_expression_list : assignment_expression - | argument_expression_list COMMA assignment_expression - """ - if len(p) == 2: # single expr - p[0] = c_ast.ExprList([p[1]], p[1].coord) - else: - p[1].exprs.append(p[3]) - p[0] = p[1] - - def p_identifier(self, p): - """ identifier : ID """ - p[0] = c_ast.ID(p[1], self._coord(p.lineno(1))) - - def p_constant_1(self, p): - """ constant : INT_CONST_DEC - | INT_CONST_OCT - | INT_CONST_HEX - """ - p[0] = c_ast.Constant( - 'int', p[1], self._coord(p.lineno(1))) - - def p_constant_2(self, p): - """ constant : FLOAT_CONST """ - p[0] = c_ast.Constant( - 'float', p[1], self._coord(p.lineno(1))) - - def p_constant_3(self, p): - """ constant : CHAR_CONST - | WCHAR_CONST - """ - p[0] = c_ast.Constant( - 'char', p[1], self._coord(p.lineno(1))) - - def p_empty(self, p): - 'empty : ' - p[0] = None - - def p_error(self, p): - if p: - self._parse_error( - 'before: %s' % p.value, - self._coord(p.lineno)) - else: - self._parse_error('At end of input', '') - - -if __name__ == "__main__": - import pprint - import time - - t1 = time.time() - parser = CParser(lex_optimize=True, yacc_debug=True, yacc_optimize=False) - print time.time() - t1 - - buf = ''' - int (*k)(int); - ''' - - # set debuglevel to 2 for debugging - t = parser.parse(buf, 'x.c', debuglevel=0) - t.show(showcoord=True) diff --git a/plugins_available/pycparser/pycparser/ply/__init__.py b/plugins_available/pycparser/pycparser/ply/__init__.py deleted file mode 100644 index 853a985..0000000 --- a/plugins_available/pycparser/pycparser/ply/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# PLY package -# Author: David Beazley (dave@dabeaz.com) - -__all__ = ['lex','yacc'] diff --git a/plugins_available/pycparser/pycparser/ply/cpp.py b/plugins_available/pycparser/pycparser/ply/cpp.py deleted file mode 100644 index 39f9d47..0000000 --- a/plugins_available/pycparser/pycparser/ply/cpp.py +++ /dev/null @@ -1,898 +0,0 @@ -# ----------------------------------------------------------------------------- -# cpp.py -# -# Author: David Beazley (http://www.dabeaz.com) -# Copyright (C) 2007 -# All rights reserved -# -# This module implements an ANSI-C style lexical preprocessor for PLY. -# ----------------------------------------------------------------------------- -from __future__ import generators - -# ----------------------------------------------------------------------------- -# Default preprocessor lexer definitions. These tokens are enough to get -# a basic preprocessor working. Other modules may import these if they want -# ----------------------------------------------------------------------------- - -tokens = ( - 'CPP_ID','CPP_INTEGER', 'CPP_FLOAT', 'CPP_STRING', 'CPP_CHAR', 'CPP_WS', 'CPP_COMMENT', 'CPP_POUND','CPP_DPOUND' -) - -literals = "+-*/%|&~^<>=!?()[]{}.,;:\\\'\"" - -# Whitespace -def t_CPP_WS(t): - r'\s+' - t.lexer.lineno += t.value.count("\n") - return t - -t_CPP_POUND = r'\#' -t_CPP_DPOUND = r'\#\#' - -# Identifier -t_CPP_ID = r'[A-Za-z_][\w_]*' - -# Integer literal -def CPP_INTEGER(t): - r'(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU]|[lL]|[uU][lL]|[lL][uU])?)' - return t - -t_CPP_INTEGER = CPP_INTEGER - -# Floating literal -t_CPP_FLOAT = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?' - -# String literal -def t_CPP_STRING(t): - r'\"([^\\\n]|(\\(.|\n)))*?\"' - t.lexer.lineno += t.value.count("\n") - return t - -# Character constant 'c' or L'c' -def t_CPP_CHAR(t): - r'(L)?\'([^\\\n]|(\\(.|\n)))*?\'' - t.lexer.lineno += t.value.count("\n") - return t - -# Comment -def t_CPP_COMMENT(t): - r'(/\*(.|\n)*?\*/)|(//.*?\n)' - t.lexer.lineno += t.value.count("\n") - return t - -def t_error(t): - t.type = t.value[0] - t.value = t.value[0] - t.lexer.skip(1) - return t - -import re -import copy -import time -import os.path - -# ----------------------------------------------------------------------------- -# trigraph() -# -# Given an input string, this function replaces all trigraph sequences. -# The following mapping is used: -# -# ??= # -# ??/ \ -# ??' ^ -# ??( [ -# ??) ] -# ??! | -# ??< { -# ??> } -# ??- ~ -# ----------------------------------------------------------------------------- - -_trigraph_pat = re.compile(r'''\?\?[=/\'\(\)\!<>\-]''') -_trigraph_rep = { - '=':'#', - '/':'\\', - "'":'^', - '(':'[', - ')':']', - '!':'|', - '<':'{', - '>':'}', - '-':'~' -} - -def trigraph(input): - return _trigraph_pat.sub(lambda g: _trigraph_rep[g.group()[-1]],input) - -# ------------------------------------------------------------------ -# Macro object -# -# This object holds information about preprocessor macros -# -# .name - Macro name (string) -# .value - Macro value (a list of tokens) -# .arglist - List of argument names -# .variadic - Boolean indicating whether or not variadic macro -# .vararg - Name of the variadic parameter -# -# When a macro is created, the macro replacement token sequence is -# pre-scanned and used to create patch lists that are later used -# during macro expansion -# ------------------------------------------------------------------ - -class Macro(object): - def __init__(self,name,value,arglist=None,variadic=False): - self.name = name - self.value = value - self.arglist = arglist - self.variadic = variadic - if variadic: - self.vararg = arglist[-1] - self.source = None - -# ------------------------------------------------------------------ -# Preprocessor object -# -# Object representing a preprocessor. Contains macro definitions, -# include directories, and other information -# ------------------------------------------------------------------ - -class Preprocessor(object): - def __init__(self,lexer=None): - if lexer is None: - lexer = lex.lexer - self.lexer = lexer - self.macros = { } - self.path = [] - self.temp_path = [] - - # Probe the lexer for selected tokens - self.lexprobe() - - tm = time.localtime() - self.define("__DATE__ \"%s\"" % time.strftime("%b %d %Y",tm)) - self.define("__TIME__ \"%s\"" % time.strftime("%H:%M:%S",tm)) - self.parser = None - - # ----------------------------------------------------------------------------- - # tokenize() - # - # Utility function. Given a string of text, tokenize into a list of tokens - # ----------------------------------------------------------------------------- - - def tokenize(self,text): - tokens = [] - self.lexer.input(text) - while True: - tok = self.lexer.token() - if not tok: break - tokens.append(tok) - return tokens - - # --------------------------------------------------------------------- - # error() - # - # Report a preprocessor error/warning of some kind - # ---------------------------------------------------------------------- - - def error(self,file,line,msg): - print >>sys.stderr,"%s:%d %s" % (file,line,msg) - - # ---------------------------------------------------------------------- - # lexprobe() - # - # This method probes the preprocessor lexer object to discover - # the token types of symbols that are important to the preprocessor. - # If this works right, the preprocessor will simply "work" - # with any suitable lexer regardless of how tokens have been named. - # ---------------------------------------------------------------------- - - def lexprobe(self): - - # Determine the token type for identifiers - self.lexer.input("identifier") - tok = self.lexer.token() - if not tok or tok.value != "identifier": - print "Couldn't determine identifier type" - else: - self.t_ID = tok.type - - # Determine the token type for integers - self.lexer.input("12345") - tok = self.lexer.token() - if not tok or int(tok.value) != 12345: - print "Couldn't determine integer type" - else: - self.t_INTEGER = tok.type - self.t_INTEGER_TYPE = type(tok.value) - - # Determine the token type for strings enclosed in double quotes - self.lexer.input("\"filename\"") - tok = self.lexer.token() - if not tok or tok.value != "\"filename\"": - print "Couldn't determine string type" - else: - self.t_STRING = tok.type - - # Determine the token type for whitespace--if any - self.lexer.input(" ") - tok = self.lexer.token() - if not tok or tok.value != " ": - self.t_SPACE = None - else: - self.t_SPACE = tok.type - - # Determine the token type for newlines - self.lexer.input("\n") - tok = self.lexer.token() - if not tok or tok.value != "\n": - self.t_NEWLINE = None - print "Couldn't determine token for newlines" - else: - self.t_NEWLINE = tok.type - - self.t_WS = (self.t_SPACE, self.t_NEWLINE) - - # Check for other characters used by the preprocessor - chars = [ '<','>','#','##','\\','(',')',',','.'] - for c in chars: - self.lexer.input(c) - tok = self.lexer.token() - if not tok or tok.value != c: - print "Unable to lex '%s' required for preprocessor" % c - - # ---------------------------------------------------------------------- - # add_path() - # - # Adds a search path to the preprocessor. - # ---------------------------------------------------------------------- - - def add_path(self,path): - self.path.append(path) - - # ---------------------------------------------------------------------- - # group_lines() - # - # Given an input string, this function splits it into lines. Trailing whitespace - # is removed. Any line ending with \ is grouped with the next line. This - # function forms the lowest level of the preprocessor---grouping into text into - # a line-by-line format. - # ---------------------------------------------------------------------- - - def group_lines(self,input): - lex = self.lexer.clone() - lines = [x.rstrip() for x in input.splitlines()] - for i in xrange(len(lines)): - j = i+1 - while lines[i].endswith('\\') and (j < len(lines)): - lines[i] = lines[i][:-1]+lines[j] - lines[j] = "" - j += 1 - - input = "\n".join(lines) - lex.input(input) - lex.lineno = 1 - - current_line = [] - while True: - tok = lex.token() - if not tok: - break - current_line.append(tok) - if tok.type in self.t_WS and '\n' in tok.value: - yield current_line - current_line = [] - - if current_line: - yield current_line - - # ---------------------------------------------------------------------- - # tokenstrip() - # - # Remove leading/trailing whitespace tokens from a token list - # ---------------------------------------------------------------------- - - def tokenstrip(self,tokens): - i = 0 - while i < len(tokens) and tokens[i].type in self.t_WS: - i += 1 - del tokens[:i] - i = len(tokens)-1 - while i >= 0 and tokens[i].type in self.t_WS: - i -= 1 - del tokens[i+1:] - return tokens - - - # ---------------------------------------------------------------------- - # collect_args() - # - # Collects comma separated arguments from a list of tokens. The arguments - # must be enclosed in parenthesis. Returns a tuple (tokencount,args,positions) - # where tokencount is the number of tokens consumed, args is a list of arguments, - # and positions is a list of integers containing the starting index of each - # argument. Each argument is represented by a list of tokens. - # - # When collecting arguments, leading and trailing whitespace is removed - # from each argument. - # - # This function properly handles nested parenthesis and commas---these do not - # define new arguments. - # ---------------------------------------------------------------------- - - def collect_args(self,tokenlist): - args = [] - positions = [] - current_arg = [] - nesting = 1 - tokenlen = len(tokenlist) - - # Search for the opening '('. - i = 0 - while (i < tokenlen) and (tokenlist[i].type in self.t_WS): - i += 1 - - if (i < tokenlen) and (tokenlist[i].value == '('): - positions.append(i+1) - else: - self.error(self.source,tokenlist[0].lineno,"Missing '(' in macro arguments") - return 0, [], [] - - i += 1 - - while i < tokenlen: - t = tokenlist[i] - if t.value == '(': - current_arg.append(t) - nesting += 1 - elif t.value == ')': - nesting -= 1 - if nesting == 0: - if current_arg: - args.append(self.tokenstrip(current_arg)) - positions.append(i) - return i+1,args,positions - current_arg.append(t) - elif t.value == ',' and nesting == 1: - args.append(self.tokenstrip(current_arg)) - positions.append(i+1) - current_arg = [] - else: - current_arg.append(t) - i += 1 - - # Missing end argument - self.error(self.source,tokenlist[-1].lineno,"Missing ')' in macro arguments") - return 0, [],[] - - # ---------------------------------------------------------------------- - # macro_prescan() - # - # Examine the macro value (token sequence) and identify patch points - # This is used to speed up macro expansion later on---we'll know - # right away where to apply patches to the value to form the expansion - # ---------------------------------------------------------------------- - - def macro_prescan(self,macro): - macro.patch = [] # Standard macro arguments - macro.str_patch = [] # String conversion expansion - macro.var_comma_patch = [] # Variadic macro comma patch - i = 0 - while i < len(macro.value): - if macro.value[i].type == self.t_ID and macro.value[i].value in macro.arglist: - argnum = macro.arglist.index(macro.value[i].value) - # Conversion of argument to a string - if i > 0 and macro.value[i-1].value == '#': - macro.value[i] = copy.copy(macro.value[i]) - macro.value[i].type = self.t_STRING - del macro.value[i-1] - macro.str_patch.append((argnum,i-1)) - continue - # Concatenation - elif (i > 0 and macro.value[i-1].value == '##'): - macro.patch.append(('c',argnum,i-1)) - del macro.value[i-1] - continue - elif ((i+1) < len(macro.value) and macro.value[i+1].value == '##'): - macro.patch.append(('c',argnum,i)) - i += 1 - continue - # Standard expansion - else: - macro.patch.append(('e',argnum,i)) - elif macro.value[i].value == '##': - if macro.variadic and (i > 0) and (macro.value[i-1].value == ',') and \ - ((i+1) < len(macro.value)) and (macro.value[i+1].type == self.t_ID) and \ - (macro.value[i+1].value == macro.vararg): - macro.var_comma_patch.append(i-1) - i += 1 - macro.patch.sort(key=lambda x: x[2],reverse=True) - - # ---------------------------------------------------------------------- - # macro_expand_args() - # - # Given a Macro and list of arguments (each a token list), this method - # returns an expanded version of a macro. The return value is a token sequence - # representing the replacement macro tokens - # ---------------------------------------------------------------------- - - def macro_expand_args(self,macro,args): - # Make a copy of the macro token sequence - rep = [copy.copy(_x) for _x in macro.value] - - # Make string expansion patches. These do not alter the length of the replacement sequence - - str_expansion = {} - for argnum, i in macro.str_patch: - if argnum not in str_expansion: - str_expansion[argnum] = ('"%s"' % "".join([x.value for x in args[argnum]])).replace("\\","\\\\") - rep[i] = copy.copy(rep[i]) - rep[i].value = str_expansion[argnum] - - # Make the variadic macro comma patch. If the variadic macro argument is empty, we get rid - comma_patch = False - if macro.variadic and not args[-1]: - for i in macro.var_comma_patch: - rep[i] = None - comma_patch = True - - # Make all other patches. The order of these matters. It is assumed that the patch list - # has been sorted in reverse order of patch location since replacements will cause the - # size of the replacement sequence to expand from the patch point. - - expanded = { } - for ptype, argnum, i in macro.patch: - # Concatenation. Argument is left unexpanded - if ptype == 'c': - rep[i:i+1] = args[argnum] - # Normal expansion. Argument is macro expanded first - elif ptype == 'e': - if argnum not in expanded: - expanded[argnum] = self.expand_macros(args[argnum]) - rep[i:i+1] = expanded[argnum] - - # Get rid of removed comma if necessary - if comma_patch: - rep = [_i for _i in rep if _i] - - return rep - - - # ---------------------------------------------------------------------- - # expand_macros() - # - # Given a list of tokens, this function performs macro expansion. - # The expanded argument is a dictionary that contains macros already - # expanded. This is used to prevent infinite recursion. - # ---------------------------------------------------------------------- - - def expand_macros(self,tokens,expanded=None): - if expanded is None: - expanded = {} - i = 0 - while i < len(tokens): - t = tokens[i] - if t.type == self.t_ID: - if t.value in self.macros and t.value not in expanded: - # Yes, we found a macro match - expanded[t.value] = True - - m = self.macros[t.value] - if not m.arglist: - # A simple macro - ex = self.expand_macros([copy.copy(_x) for _x in m.value],expanded) - for e in ex: - e.lineno = t.lineno - tokens[i:i+1] = ex - i += len(ex) - else: - # A macro with arguments - j = i + 1 - while j < len(tokens) and tokens[j].type in self.t_WS: - j += 1 - if tokens[j].value == '(': - tokcount,args,positions = self.collect_args(tokens[j:]) - if not m.variadic and len(args) != len(m.arglist): - self.error(self.source,t.lineno,"Macro %s requires %d arguments" % (t.value,len(m.arglist))) - i = j + tokcount - elif m.variadic and len(args) < len(m.arglist)-1: - if len(m.arglist) > 2: - self.error(self.source,t.lineno,"Macro %s must have at least %d arguments" % (t.value, len(m.arglist)-1)) - else: - self.error(self.source,t.lineno,"Macro %s must have at least %d argument" % (t.value, len(m.arglist)-1)) - i = j + tokcount - else: - if m.variadic: - if len(args) == len(m.arglist)-1: - args.append([]) - else: - args[len(m.arglist)-1] = tokens[j+positions[len(m.arglist)-1]:j+tokcount-1] - del args[len(m.arglist):] - - # Get macro replacement text - rep = self.macro_expand_args(m,args) - rep = self.expand_macros(rep,expanded) - for r in rep: - r.lineno = t.lineno - tokens[i:j+tokcount] = rep - i += len(rep) - del expanded[t.value] - continue - elif t.value == '__LINE__': - t.type = self.t_INTEGER - t.value = self.t_INTEGER_TYPE(t.lineno) - - i += 1 - return tokens - - # ---------------------------------------------------------------------- - # evalexpr() - # - # Evaluate an expression token sequence for the purposes of evaluating - # integral expressions. - # ---------------------------------------------------------------------- - - def evalexpr(self,tokens): - # tokens = tokenize(line) - # Search for defined macros - i = 0 - while i < len(tokens): - if tokens[i].type == self.t_ID and tokens[i].value == 'defined': - j = i + 1 - needparen = False - result = "0L" - while j < len(tokens): - if tokens[j].type in self.t_WS: - j += 1 - continue - elif tokens[j].type == self.t_ID: - if tokens[j].value in self.macros: - result = "1L" - else: - result = "0L" - if not needparen: break - elif tokens[j].value == '(': - needparen = True - elif tokens[j].value == ')': - break - else: - self.error(self.source,tokens[i].lineno,"Malformed defined()") - j += 1 - tokens[i].type = self.t_INTEGER - tokens[i].value = self.t_INTEGER_TYPE(result) - del tokens[i+1:j+1] - i += 1 - tokens = self.expand_macros(tokens) - for i,t in enumerate(tokens): - if t.type == self.t_ID: - tokens[i] = copy.copy(t) - tokens[i].type = self.t_INTEGER - tokens[i].value = self.t_INTEGER_TYPE("0L") - elif t.type == self.t_INTEGER: - tokens[i] = copy.copy(t) - # Strip off any trailing suffixes - tokens[i].value = str(tokens[i].value) - while tokens[i].value[-1] not in "0123456789abcdefABCDEF": - tokens[i].value = tokens[i].value[:-1] - - expr = "".join([str(x.value) for x in tokens]) - expr = expr.replace("&&"," and ") - expr = expr.replace("||"," or ") - expr = expr.replace("!"," not ") - try: - result = eval(expr) - except StandardError: - self.error(self.source,tokens[0].lineno,"Couldn't evaluate expression") - result = 0 - return result - - # ---------------------------------------------------------------------- - # parsegen() - # - # Parse an input string/ - # ---------------------------------------------------------------------- - def parsegen(self,input,source=None): - - # Replace trigraph sequences - t = trigraph(input) - lines = self.group_lines(t) - - if not source: - source = "" - - self.define("__FILE__ \"%s\"" % source) - - self.source = source - chunk = [] - enable = True - iftrigger = False - ifstack = [] - - for x in lines: - for i,tok in enumerate(x): - if tok.type not in self.t_WS: break - if tok.value == '#': - # Preprocessor directive - - for tok in x: - if tok in self.t_WS and '\n' in tok.value: - chunk.append(tok) - - dirtokens = self.tokenstrip(x[i+1:]) - if dirtokens: - name = dirtokens[0].value - args = self.tokenstrip(dirtokens[1:]) - else: - name = "" - args = [] - - if name == 'define': - if enable: - for tok in self.expand_macros(chunk): - yield tok - chunk = [] - self.define(args) - elif name == 'include': - if enable: - for tok in self.expand_macros(chunk): - yield tok - chunk = [] - oldfile = self.macros['__FILE__'] - for tok in self.include(args): - yield tok - self.macros['__FILE__'] = oldfile - self.source = source - elif name == 'undef': - if enable: - for tok in self.expand_macros(chunk): - yield tok - chunk = [] - self.undef(args) - elif name == 'ifdef': - ifstack.append((enable,iftrigger)) - if enable: - if not args[0].value in self.macros: - enable = False - iftrigger = False - else: - iftrigger = True - elif name == 'ifndef': - ifstack.append((enable,iftrigger)) - if enable: - if args[0].value in self.macros: - enable = False - iftrigger = False - else: - iftrigger = True - elif name == 'if': - ifstack.append((enable,iftrigger)) - if enable: - result = self.evalexpr(args) - if not result: - enable = False - iftrigger = False - else: - iftrigger = True - elif name == 'elif': - if ifstack: - if ifstack[-1][0]: # We only pay attention if outer "if" allows this - if enable: # If already true, we flip enable False - enable = False - elif not iftrigger: # If False, but not triggered yet, we'll check expression - result = self.evalexpr(args) - if result: - enable = True - iftrigger = True - else: - self.error(self.source,dirtokens[0].lineno,"Misplaced #elif") - - elif name == 'else': - if ifstack: - if ifstack[-1][0]: - if enable: - enable = False - elif not iftrigger: - enable = True - iftrigger = True - else: - self.error(self.source,dirtokens[0].lineno,"Misplaced #else") - - elif name == 'endif': - if ifstack: - enable,iftrigger = ifstack.pop() - else: - self.error(self.source,dirtokens[0].lineno,"Misplaced #endif") - else: - # Unknown preprocessor directive - pass - - else: - # Normal text - if enable: - chunk.extend(x) - - for tok in self.expand_macros(chunk): - yield tok - chunk = [] - - # ---------------------------------------------------------------------- - # include() - # - # Implementation of file-inclusion - # ---------------------------------------------------------------------- - - def include(self,tokens): - # Try to extract the filename and then process an include file - if not tokens: - return - if tokens: - if tokens[0].value != '<' and tokens[0].type != self.t_STRING: - tokens = self.expand_macros(tokens) - - if tokens[0].value == '<': - # Include <...> - i = 1 - while i < len(tokens): - if tokens[i].value == '>': - break - i += 1 - else: - print "Malformed #include <...>" - return - filename = "".join([x.value for x in tokens[1:i]]) - path = self.path + [""] + self.temp_path - elif tokens[0].type == self.t_STRING: - filename = tokens[0].value[1:-1] - path = self.temp_path + [""] + self.path - else: - print "Malformed #include statement" - return - for p in path: - iname = os.path.join(p,filename) - try: - data = open(iname,"r").read() - dname = os.path.dirname(iname) - if dname: - self.temp_path.insert(0,dname) - for tok in self.parsegen(data,filename): - yield tok - if dname: - del self.temp_path[0] - break - except IOError,e: - pass - else: - print "Couldn't find '%s'" % filename - - # ---------------------------------------------------------------------- - # define() - # - # Define a new macro - # ---------------------------------------------------------------------- - - def define(self,tokens): - if isinstance(tokens,(str,unicode)): - tokens = self.tokenize(tokens) - - linetok = tokens - try: - name = linetok[0] - if len(linetok) > 1: - mtype = linetok[1] - else: - mtype = None - if not mtype: - m = Macro(name.value,[]) - self.macros[name.value] = m - elif mtype.type in self.t_WS: - # A normal macro - m = Macro(name.value,self.tokenstrip(linetok[2:])) - self.macros[name.value] = m - elif mtype.value == '(': - # A macro with arguments - tokcount, args, positions = self.collect_args(linetok[1:]) - variadic = False - for a in args: - if variadic: - print "No more arguments may follow a variadic argument" - break - astr = "".join([str(_i.value) for _i in a]) - if astr == "...": - variadic = True - a[0].type = self.t_ID - a[0].value = '__VA_ARGS__' - variadic = True - del a[1:] - continue - elif astr[-3:] == "..." and a[0].type == self.t_ID: - variadic = True - del a[1:] - # If, for some reason, "." is part of the identifier, strip off the name for the purposes - # of macro expansion - if a[0].value[-3:] == '...': - a[0].value = a[0].value[:-3] - continue - if len(a) > 1 or a[0].type != self.t_ID: - print "Invalid macro argument" - break - else: - mvalue = self.tokenstrip(linetok[1+tokcount:]) - i = 0 - while i < len(mvalue): - if i+1 < len(mvalue): - if mvalue[i].type in self.t_WS and mvalue[i+1].value == '##': - del mvalue[i] - continue - elif mvalue[i].value == '##' and mvalue[i+1].type in self.t_WS: - del mvalue[i+1] - i += 1 - m = Macro(name.value,mvalue,[x[0].value for x in args],variadic) - self.macro_prescan(m) - self.macros[name.value] = m - else: - print "Bad macro definition" - except LookupError: - print "Bad macro definition" - - # ---------------------------------------------------------------------- - # undef() - # - # Undefine a macro - # ---------------------------------------------------------------------- - - def undef(self,tokens): - id = tokens[0].value - try: - del self.macros[id] - except LookupError: - pass - - # ---------------------------------------------------------------------- - # parse() - # - # Parse input text. - # ---------------------------------------------------------------------- - def parse(self,input,source=None,ignore={}): - self.ignore = ignore - self.parser = self.parsegen(input,source) - - # ---------------------------------------------------------------------- - # token() - # - # Method to return individual tokens - # ---------------------------------------------------------------------- - def token(self): - try: - while True: - tok = self.parser.next() - if tok.type not in self.ignore: return tok - except StopIteration: - self.parser = None - return None - -if __name__ == '__main__': - import ply.lex as lex - lexer = lex.lex() - - # Run a preprocessor - import sys - f = open(sys.argv[1]) - input = f.read() - - p = Preprocessor(lexer) - p.parse(input,sys.argv[1]) - while True: - tok = p.token() - if not tok: break - print p.source, tok - - - - - - - - - - - diff --git a/plugins_available/pycparser/pycparser/ply/ctokens.py b/plugins_available/pycparser/pycparser/ply/ctokens.py deleted file mode 100644 index dd5f102..0000000 --- a/plugins_available/pycparser/pycparser/ply/ctokens.py +++ /dev/null @@ -1,133 +0,0 @@ -# ---------------------------------------------------------------------- -# ctokens.py -# -# Token specifications for symbols in ANSI C and C++. This file is -# meant to be used as a library in other tokenizers. -# ---------------------------------------------------------------------- - -# Reserved words - -tokens = [ - # Literals (identifier, integer constant, float constant, string constant, char const) - 'ID', 'TYPEID', 'ICONST', 'FCONST', 'SCONST', 'CCONST', - - # Operators (+,-,*,/,%,|,&,~,^,<<,>>, ||, &&, !, <, <=, >, >=, ==, !=) - 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD', - 'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT', - 'LOR', 'LAND', 'LNOT', - 'LT', 'LE', 'GT', 'GE', 'EQ', 'NE', - - # Assignment (=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=) - 'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL', 'PLUSEQUAL', 'MINUSEQUAL', - 'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL', 'OREQUAL', - - # Increment/decrement (++,--) - 'PLUSPLUS', 'MINUSMINUS', - - # Structure dereference (->) - 'ARROW', - - # Ternary operator (?) - 'TERNARY', - - # Delimeters ( ) [ ] { } , . ; : - 'LPAREN', 'RPAREN', - 'LBRACKET', 'RBRACKET', - 'LBRACE', 'RBRACE', - 'COMMA', 'PERIOD', 'SEMI', 'COLON', - - # Ellipsis (...) - 'ELLIPSIS', -] - -# Operators -t_PLUS = r'\+' -t_MINUS = r'-' -t_TIMES = r'\*' -t_DIVIDE = r'/' -t_MODULO = r'%' -t_OR = r'\|' -t_AND = r'&' -t_NOT = r'~' -t_XOR = r'\^' -t_LSHIFT = r'<<' -t_RSHIFT = r'>>' -t_LOR = r'\|\|' -t_LAND = r'&&' -t_LNOT = r'!' -t_LT = r'<' -t_GT = r'>' -t_LE = r'<=' -t_GE = r'>=' -t_EQ = r'==' -t_NE = r'!=' - -# Assignment operators - -t_EQUALS = r'=' -t_TIMESEQUAL = r'\*=' -t_DIVEQUAL = r'/=' -t_MODEQUAL = r'%=' -t_PLUSEQUAL = r'\+=' -t_MINUSEQUAL = r'-=' -t_LSHIFTEQUAL = r'<<=' -t_RSHIFTEQUAL = r'>>=' -t_ANDEQUAL = r'&=' -t_OREQUAL = r'\|=' -t_XOREQUAL = r'^=' - -# Increment/decrement -t_INCREMENT = r'\+\+' -t_DECREMENT = r'--' - -# -> -t_ARROW = r'->' - -# ? -t_TERNARY = r'\?' - -# Delimeters -t_LPAREN = r'\(' -t_RPAREN = r'\)' -t_LBRACKET = r'\[' -t_RBRACKET = r'\]' -t_LBRACE = r'\{' -t_RBRACE = r'\}' -t_COMMA = r',' -t_PERIOD = r'\.' -t_SEMI = r';' -t_COLON = r':' -t_ELLIPSIS = r'\.\.\.' - -# Identifiers -t_ID = r'[A-Za-z_][A-Za-z0-9_]*' - -# Integer literal -t_INTEGER = r'\d+([uU]|[lL]|[uU][lL]|[lL][uU])?' - -# Floating literal -t_FLOAT = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?' - -# String literal -t_STRING = r'\"([^\\\n]|(\\.))*?\"' - -# Character constant 'c' or L'c' -t_CHARACTER = r'(L)?\'([^\\\n]|(\\.))*?\'' - -# Comment (C-Style) -def t_COMMENT(t): - r'/\*(.|\n)*?\*/' - t.lexer.lineno += t.value.count('\n') - return t - -# Comment (C++-Style) -def t_CPPCOMMENT(t): - r'//.*\n' - t.lexer.lineno += 1 - return t - - - - - - diff --git a/plugins_available/pycparser/pycparser/ply/lex.py b/plugins_available/pycparser/pycparser/ply/lex.py deleted file mode 100644 index 37a9993..0000000 --- a/plugins_available/pycparser/pycparser/ply/lex.py +++ /dev/null @@ -1,1021 +0,0 @@ -# ----------------------------------------------------------------------------- -# ply: lex.py -# -# Copyright (C) 2001-2009, -# David M. Beazley (Dabeaz LLC) -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of the David Beazley or Dabeaz LLC may be used to -# endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ----------------------------------------------------------------------------- - -__version__ = "3.3" -__tabversion__ = "3.2" # Version of table file used - -import re, sys, types, copy, os - -# This tuple contains known string types -try: - # Python 2.6 - StringTypes = (types.StringType, types.UnicodeType) -except AttributeError: - # Python 3.0 - StringTypes = (str, bytes) - -# Extract the code attribute of a function. Different implementations -# are for Python 2/3 compatibility. - -if sys.version_info[0] < 3: - def func_code(f): - return f.func_code -else: - def func_code(f): - return f.__code__ - -# This regular expression is used to match valid token names -_is_identifier = re.compile(r'^[a-zA-Z0-9_]+$') - -# Exception thrown when invalid token encountered and no default error -# handler is defined. - -class LexError(Exception): - def __init__(self,message,s): - self.args = (message,) - self.text = s - -# Token class. This class is used to represent the tokens produced. -class LexToken(object): - def __str__(self): - return "LexToken(%s,%r,%d,%d)" % (self.type,self.value,self.lineno,self.lexpos) - def __repr__(self): - return str(self) - -# This object is a stand-in for a logging object created by the -# logging module. - -class PlyLogger(object): - def __init__(self,f): - self.f = f - def critical(self,msg,*args,**kwargs): - self.f.write((msg % args) + "\n") - - def warning(self,msg,*args,**kwargs): - self.f.write("WARNING: "+ (msg % args) + "\n") - - def error(self,msg,*args,**kwargs): - self.f.write("ERROR: " + (msg % args) + "\n") - - info = critical - debug = critical - -# Null logger is used when no output is generated. Does nothing. -class NullLogger(object): - def __getattribute__(self,name): - return self - def __call__(self,*args,**kwargs): - return self - -# ----------------------------------------------------------------------------- -# === Lexing Engine === -# -# The following Lexer class implements the lexer runtime. There are only -# a few public methods and attributes: -# -# input() - Store a new string in the lexer -# token() - Get the next token -# clone() - Clone the lexer -# -# lineno - Current line number -# lexpos - Current position in the input string -# ----------------------------------------------------------------------------- - -class Lexer: - def __init__(self): - self.lexre = None # Master regular expression. This is a list of - # tuples (re,findex) where re is a compiled - # regular expression and findex is a list - # mapping regex group numbers to rules - self.lexretext = None # Current regular expression strings - self.lexstatere = {} # Dictionary mapping lexer states to master regexs - self.lexstateretext = {} # Dictionary mapping lexer states to regex strings - self.lexstaterenames = {} # Dictionary mapping lexer states to symbol names - self.lexstate = "INITIAL" # Current lexer state - self.lexstatestack = [] # Stack of lexer states - self.lexstateinfo = None # State information - self.lexstateignore = {} # Dictionary of ignored characters for each state - self.lexstateerrorf = {} # Dictionary of error functions for each state - self.lexreflags = 0 # Optional re compile flags - self.lexdata = None # Actual input data (as a string) - self.lexpos = 0 # Current position in input text - self.lexlen = 0 # Length of the input text - self.lexerrorf = None # Error rule (if any) - self.lextokens = None # List of valid tokens - self.lexignore = "" # Ignored characters - self.lexliterals = "" # Literal characters that can be passed through - self.lexmodule = None # Module - self.lineno = 1 # Current line number - self.lexoptimize = 0 # Optimized mode - - def clone(self,object=None): - c = copy.copy(self) - - # If the object parameter has been supplied, it means we are attaching the - # lexer to a new object. In this case, we have to rebind all methods in - # the lexstatere and lexstateerrorf tables. - - if object: - newtab = { } - for key, ritem in self.lexstatere.items(): - newre = [] - for cre, findex in ritem: - newfindex = [] - for f in findex: - if not f or not f[0]: - newfindex.append(f) - continue - newfindex.append((getattr(object,f[0].__name__),f[1])) - newre.append((cre,newfindex)) - newtab[key] = newre - c.lexstatere = newtab - c.lexstateerrorf = { } - for key, ef in self.lexstateerrorf.items(): - c.lexstateerrorf[key] = getattr(object,ef.__name__) - c.lexmodule = object - return c - - # ------------------------------------------------------------ - # writetab() - Write lexer information to a table file - # ------------------------------------------------------------ - def writetab(self,tabfile,outputdir=""): - return - - # ------------------------------------------------------------ - # readtab() - Read lexer information from a tab file - # ------------------------------------------------------------ - def readtab(self,tabfile,fdict): - if isinstance(tabfile,types.ModuleType): - lextab = tabfile - else: - if sys.version_info[0] < 3: - exec("import %s as lextab" % tabfile) - else: - env = { } - exec("import %s as lextab" % tabfile, env,env) - lextab = env['lextab'] - - if getattr(lextab,"_tabversion","0.0") != __version__: - raise ImportError("Inconsistent PLY version") - - self.lextokens = lextab._lextokens - self.lexreflags = lextab._lexreflags - self.lexliterals = lextab._lexliterals - self.lexstateinfo = lextab._lexstateinfo - self.lexstateignore = lextab._lexstateignore - self.lexstatere = { } - self.lexstateretext = { } - for key,lre in lextab._lexstatere.items(): - titem = [] - txtitem = [] - for i in range(len(lre)): - titem.append((re.compile(lre[i][0],lextab._lexreflags | re.VERBOSE),_names_to_funcs(lre[i][1],fdict))) - txtitem.append(lre[i][0]) - self.lexstatere[key] = titem - self.lexstateretext[key] = txtitem - self.lexstateerrorf = { } - for key,ef in lextab._lexstateerrorf.items(): - self.lexstateerrorf[key] = fdict[ef] - self.begin('INITIAL') - - # ------------------------------------------------------------ - # input() - Push a new string into the lexer - # ------------------------------------------------------------ - def input(self,s): - # Pull off the first character to see if s looks like a string - c = s[:1] - if not isinstance(c,StringTypes): - raise ValueError("Expected a string") - self.lexdata = s - self.lexpos = 0 - self.lexlen = len(s) - - # ------------------------------------------------------------ - # begin() - Changes the lexing state - # ------------------------------------------------------------ - def begin(self,state): - if not state in self.lexstatere: - raise ValueError("Undefined state") - self.lexre = self.lexstatere[state] - self.lexretext = self.lexstateretext[state] - self.lexignore = self.lexstateignore.get(state,"") - self.lexerrorf = self.lexstateerrorf.get(state,None) - self.lexstate = state - - # ------------------------------------------------------------ - # push_state() - Changes the lexing state and saves old on stack - # ------------------------------------------------------------ - def push_state(self,state): - self.lexstatestack.append(self.lexstate) - self.begin(state) - - # ------------------------------------------------------------ - # pop_state() - Restores the previous state - # ------------------------------------------------------------ - def pop_state(self): - self.begin(self.lexstatestack.pop()) - - # ------------------------------------------------------------ - # current_state() - Returns the current lexing state - # ------------------------------------------------------------ - def current_state(self): - return self.lexstate - - # ------------------------------------------------------------ - # skip() - Skip ahead n characters - # ------------------------------------------------------------ - def skip(self,n): - self.lexpos += n - - # ------------------------------------------------------------ - # opttoken() - Return the next token from the Lexer - # - # Note: This function has been carefully implemented to be as fast - # as possible. Don't make changes unless you really know what - # you are doing - # ------------------------------------------------------------ - def token(self): - # Make local copies of frequently referenced attributes - lexpos = self.lexpos - lexlen = self.lexlen - lexignore = self.lexignore - lexdata = self.lexdata - - while lexpos < lexlen: - # This code provides some short-circuit code for whitespace, tabs, and other ignored characters - if lexdata[lexpos] in lexignore: - lexpos += 1 - continue - - # Look for a regular expression match - for lexre,lexindexfunc in self.lexre: - m = lexre.match(lexdata,lexpos) - if not m: continue - - # Create a token for return - tok = LexToken() - tok.value = m.group() - tok.lineno = self.lineno - tok.lexpos = lexpos - - i = m.lastindex - func,tok.type = lexindexfunc[i] - - if not func: - # If no token type was set, it's an ignored token - if tok.type: - self.lexpos = m.end() - return tok - else: - lexpos = m.end() - break - - lexpos = m.end() - - # If token is processed by a function, call it - - tok.lexer = self # Set additional attributes useful in token rules - self.lexmatch = m - self.lexpos = lexpos - - newtok = func(tok) - - # Every function must return a token, if nothing, we just move to next token - if not newtok: - lexpos = self.lexpos # This is here in case user has updated lexpos. - lexignore = self.lexignore # This is here in case there was a state change - break - - # Verify type of the token. If not in the token map, raise an error - if not self.lexoptimize: - if not newtok.type in self.lextokens: - raise LexError("%s:%d: Rule '%s' returned an unknown token type '%s'" % ( - func_code(func).co_filename, func_code(func).co_firstlineno, - func.__name__, newtok.type),lexdata[lexpos:]) - - return newtok - else: - # No match, see if in literals - if lexdata[lexpos] in self.lexliterals: - tok = LexToken() - tok.value = lexdata[lexpos] - tok.lineno = self.lineno - tok.type = tok.value - tok.lexpos = lexpos - self.lexpos = lexpos + 1 - return tok - - # No match. Call t_error() if defined. - if self.lexerrorf: - tok = LexToken() - tok.value = self.lexdata[lexpos:] - tok.lineno = self.lineno - tok.type = "error" - tok.lexer = self - tok.lexpos = lexpos - self.lexpos = lexpos - newtok = self.lexerrorf(tok) - if lexpos == self.lexpos: - # Error method didn't change text position at all. This is an error. - raise LexError("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:]) - lexpos = self.lexpos - if not newtok: continue - return newtok - - self.lexpos = lexpos - raise LexError("Illegal character '%s' at index %d" % (lexdata[lexpos],lexpos), lexdata[lexpos:]) - - self.lexpos = lexpos + 1 - if self.lexdata is None: - raise RuntimeError("No input string given with input()") - return None - - # Iterator interface - def __iter__(self): - return self - - def next(self): - t = self.token() - if t is None: - raise StopIteration - return t - - __next__ = next - -# ----------------------------------------------------------------------------- -# ==== Lex Builder === -# -# The functions and classes below are used to collect lexing information -# and build a Lexer object from it. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# get_caller_module_dict() -# -# This function returns a dictionary containing all of the symbols defined within -# a caller further down the call stack. This is used to get the environment -# associated with the yacc() call if none was provided. -# ----------------------------------------------------------------------------- - -def get_caller_module_dict(levels): - try: - raise RuntimeError - except RuntimeError: - e,b,t = sys.exc_info() - f = t.tb_frame - while levels > 0: - f = f.f_back - levels -= 1 - ldict = f.f_globals.copy() - if f.f_globals != f.f_locals: - ldict.update(f.f_locals) - - return ldict - -# ----------------------------------------------------------------------------- -# _funcs_to_names() -# -# Given a list of regular expression functions, this converts it to a list -# suitable for output to a table file -# ----------------------------------------------------------------------------- - -def _funcs_to_names(funclist,namelist): - result = [] - for f,name in zip(funclist,namelist): - if f and f[0]: - result.append((name, f[1])) - else: - result.append(f) - return result - -# ----------------------------------------------------------------------------- -# _names_to_funcs() -# -# Given a list of regular expression function names, this converts it back to -# functions. -# ----------------------------------------------------------------------------- - -def _names_to_funcs(namelist,fdict): - result = [] - for n in namelist: - if n and n[0]: - result.append((fdict[n[0]],n[1])) - else: - result.append(n) - return result - -# ----------------------------------------------------------------------------- -# _form_master_re() -# -# This function takes a list of all of the regex components and attempts to -# form the master regular expression. Given limitations in the Python re -# module, it may be necessary to break the master regex into separate expressions. -# ----------------------------------------------------------------------------- - -def _form_master_re(relist,reflags,ldict,toknames): - if not relist: return [] - regex = "|".join(relist) - try: - lexre = re.compile(regex,re.VERBOSE | reflags) - - # Build the index to function map for the matching engine - lexindexfunc = [ None ] * (max(lexre.groupindex.values())+1) - lexindexnames = lexindexfunc[:] - - for f,i in lexre.groupindex.items(): - handle = ldict.get(f,None) - if type(handle) in (types.FunctionType, types.MethodType): - lexindexfunc[i] = (handle,toknames[f]) - lexindexnames[i] = f - elif handle is not None: - lexindexnames[i] = f - if f.find("ignore_") > 0: - lexindexfunc[i] = (None,None) - else: - lexindexfunc[i] = (None, toknames[f]) - - return [(lexre,lexindexfunc)],[regex],[lexindexnames] - except Exception: - m = int(len(relist)/2) - if m == 0: m = 1 - llist, lre, lnames = _form_master_re(relist[:m],reflags,ldict,toknames) - rlist, rre, rnames = _form_master_re(relist[m:],reflags,ldict,toknames) - return llist+rlist, lre+rre, lnames+rnames - -# ----------------------------------------------------------------------------- -# def _statetoken(s,names) -# -# Given a declaration name s of the form "t_" and a dictionary whose keys are -# state names, this function returns a tuple (states,tokenname) where states -# is a tuple of state names and tokenname is the name of the token. For example, -# calling this with s = "t_foo_bar_SPAM" might return (('foo','bar'),'SPAM') -# ----------------------------------------------------------------------------- - -def _statetoken(s,names): - nonstate = 1 - parts = s.split("_") - for i in range(1,len(parts)): - if not parts[i] in names and parts[i] != 'ANY': break - if i > 1: - states = tuple(parts[1:i]) - else: - states = ('INITIAL',) - - if 'ANY' in states: - states = tuple(names) - - tokenname = "_".join(parts[i:]) - return (states,tokenname) - - -# ----------------------------------------------------------------------------- -# LexerReflect() -# -# This class represents information needed to build a lexer as extracted from a -# user's input file. -# ----------------------------------------------------------------------------- -class LexerReflect(object): - def __init__(self,ldict,log=None,reflags=0): - self.ldict = ldict - self.error_func = None - self.tokens = [] - self.reflags = reflags - self.stateinfo = { 'INITIAL' : 'inclusive'} - self.files = {} - self.error = 0 - - if log is None: - self.log = PlyLogger(sys.stderr) - else: - self.log = log - - # Get all of the basic information - def get_all(self): - self.get_tokens() - self.get_literals() - self.get_states() - self.get_rules() - - # Validate all of the information - def validate_all(self): - self.validate_tokens() - self.validate_literals() - self.validate_rules() - return self.error - - # Get the tokens map - def get_tokens(self): - tokens = self.ldict.get("tokens",None) - if not tokens: - self.log.error("No token list is defined") - self.error = 1 - return - - if not isinstance(tokens,(list, tuple)): - self.log.error("tokens must be a list or tuple") - self.error = 1 - return - - if not tokens: - self.log.error("tokens is empty") - self.error = 1 - return - - self.tokens = tokens - - # Validate the tokens - def validate_tokens(self): - terminals = {} - for n in self.tokens: - if not _is_identifier.match(n): - self.log.error("Bad token name '%s'",n) - self.error = 1 - if n in terminals: - self.log.warning("Token '%s' multiply defined", n) - terminals[n] = 1 - - # Get the literals specifier - def get_literals(self): - self.literals = self.ldict.get("literals","") - - # Validate literals - def validate_literals(self): - try: - for c in self.literals: - if not isinstance(c,StringTypes) or len(c) > 1: - self.log.error("Invalid literal %s. Must be a single character", repr(c)) - self.error = 1 - continue - - except TypeError: - self.log.error("Invalid literals specification. literals must be a sequence of characters") - self.error = 1 - - def get_states(self): - self.states = self.ldict.get("states",None) - # Build statemap - if self.states: - if not isinstance(self.states,(tuple,list)): - self.log.error("states must be defined as a tuple or list") - self.error = 1 - else: - for s in self.states: - if not isinstance(s,tuple) or len(s) != 2: - self.log.error("Invalid state specifier %s. Must be a tuple (statename,'exclusive|inclusive')",repr(s)) - self.error = 1 - continue - name, statetype = s - if not isinstance(name,StringTypes): - self.log.error("State name %s must be a string", repr(name)) - self.error = 1 - continue - if not (statetype == 'inclusive' or statetype == 'exclusive'): - self.log.error("State type for state %s must be 'inclusive' or 'exclusive'",name) - self.error = 1 - continue - if name in self.stateinfo: - self.log.error("State '%s' already defined",name) - self.error = 1 - continue - self.stateinfo[name] = statetype - - # Get all of the symbols with a t_ prefix and sort them into various - # categories (functions, strings, error functions, and ignore characters) - - def get_rules(self): - tsymbols = [f for f in self.ldict if f[:2] == 't_' ] - - # Now build up a list of functions and a list of strings - - self.toknames = { } # Mapping of symbols to token names - self.funcsym = { } # Symbols defined as functions - self.strsym = { } # Symbols defined as strings - self.ignore = { } # Ignore strings by state - self.errorf = { } # Error functions by state - - for s in self.stateinfo: - self.funcsym[s] = [] - self.strsym[s] = [] - - if len(tsymbols) == 0: - self.log.error("No rules of the form t_rulename are defined") - self.error = 1 - return - - for f in tsymbols: - t = self.ldict[f] - states, tokname = _statetoken(f,self.stateinfo) - self.toknames[f] = tokname - - if hasattr(t,"__call__"): - if tokname == 'error': - for s in states: - self.errorf[s] = t - elif tokname == 'ignore': - line = func_code(t).co_firstlineno - file = func_code(t).co_filename - self.log.error("%s:%d: Rule '%s' must be defined as a string",file,line,t.__name__) - self.error = 1 - else: - for s in states: - self.funcsym[s].append((f,t)) - elif isinstance(t, StringTypes): - if tokname == 'ignore': - for s in states: - self.ignore[s] = t - if "\\" in t: - self.log.warning("%s contains a literal backslash '\\'",f) - - elif tokname == 'error': - self.log.error("Rule '%s' must be defined as a function", f) - self.error = 1 - else: - for s in states: - self.strsym[s].append((f,t)) - else: - self.log.error("%s not defined as a function or string", f) - self.error = 1 - - # Sort the functions by line number - for f in self.funcsym.values(): - if sys.version_info[0] < 3: - f.sort(lambda x,y: cmp(func_code(x[1]).co_firstlineno,func_code(y[1]).co_firstlineno)) - else: - # Python 3.0 - f.sort(key=lambda x: func_code(x[1]).co_firstlineno) - - # Sort the strings by regular expression length - for s in self.strsym.values(): - if sys.version_info[0] < 3: - s.sort(lambda x,y: (len(x[1]) < len(y[1])) - (len(x[1]) > len(y[1]))) - else: - # Python 3.0 - s.sort(key=lambda x: len(x[1]),reverse=True) - - # Validate all of the t_rules collected - def validate_rules(self): - for state in self.stateinfo: - # Validate all rules defined by functions - - - - for fname, f in self.funcsym[state]: - line = func_code(f).co_firstlineno - file = func_code(f).co_filename - self.files[file] = 1 - - tokname = self.toknames[fname] - if isinstance(f, types.MethodType): - reqargs = 2 - else: - reqargs = 1 - nargs = func_code(f).co_argcount - if nargs > reqargs: - self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,f.__name__) - self.error = 1 - continue - - if nargs < reqargs: - self.log.error("%s:%d: Rule '%s' requires an argument", file,line,f.__name__) - self.error = 1 - continue - - if not f.__doc__: - self.log.error("%s:%d: No regular expression defined for rule '%s'",file,line,f.__name__) - self.error = 1 - continue - - try: - c = re.compile("(?P<%s>%s)" % (fname,f.__doc__), re.VERBOSE | self.reflags) - if c.match(""): - self.log.error("%s:%d: Regular expression for rule '%s' matches empty string", file,line,f.__name__) - self.error = 1 - except re.error: - _etype, e, _etrace = sys.exc_info() - self.log.error("%s:%d: Invalid regular expression for rule '%s'. %s", file,line,f.__name__,e) - if '#' in f.__doc__: - self.log.error("%s:%d. Make sure '#' in rule '%s' is escaped with '\\#'",file,line, f.__name__) - self.error = 1 - - # Validate all rules defined by strings - for name,r in self.strsym[state]: - tokname = self.toknames[name] - if tokname == 'error': - self.log.error("Rule '%s' must be defined as a function", name) - self.error = 1 - continue - - if not tokname in self.tokens and tokname.find("ignore_") < 0: - self.log.error("Rule '%s' defined for an unspecified token %s",name,tokname) - self.error = 1 - continue - - try: - c = re.compile("(?P<%s>%s)" % (name,r),re.VERBOSE | self.reflags) - if (c.match("")): - self.log.error("Regular expression for rule '%s' matches empty string",name) - self.error = 1 - except re.error: - _etype, e, _etrace = sys.exc_info() - self.log.error("Invalid regular expression for rule '%s'. %s",name,e) - if '#' in r: - self.log.error("Make sure '#' in rule '%s' is escaped with '\\#'",name) - self.error = 1 - - if not self.funcsym[state] and not self.strsym[state]: - self.log.error("No rules defined for state '%s'",state) - self.error = 1 - - # Validate the error function - efunc = self.errorf.get(state,None) - if efunc: - f = efunc - line = func_code(f).co_firstlineno - file = func_code(f).co_filename - self.files[file] = 1 - - if isinstance(f, types.MethodType): - reqargs = 2 - else: - reqargs = 1 - nargs = func_code(f).co_argcount - if nargs > reqargs: - self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,f.__name__) - self.error = 1 - - if nargs < reqargs: - self.log.error("%s:%d: Rule '%s' requires an argument", file,line,f.__name__) - self.error = 1 - - for f in self.files: - self.validate_file(f) - - - # ----------------------------------------------------------------------------- - # validate_file() - # - # This checks to see if there are duplicated t_rulename() functions or strings - # in the parser input file. This is done using a simple regular expression - # match on each line in the given file. - # ----------------------------------------------------------------------------- - - def validate_file(self,filename): - import os.path - base,ext = os.path.splitext(filename) - if ext != '.py': return # No idea what the file is. Return OK - - try: - f = open(filename) - lines = f.readlines() - f.close() - except IOError: - return # Couldn't find the file. Don't worry about it - - fre = re.compile(r'\s*def\s+(t_[a-zA-Z_0-9]*)\(') - sre = re.compile(r'\s*(t_[a-zA-Z_0-9]*)\s*=') - - counthash = { } - linen = 1 - for l in lines: - m = fre.match(l) - if not m: - m = sre.match(l) - if m: - name = m.group(1) - prev = counthash.get(name) - if not prev: - counthash[name] = linen - else: - self.log.error("%s:%d: Rule %s redefined. Previously defined on line %d",filename,linen,name,prev) - self.error = 1 - linen += 1 - -# ----------------------------------------------------------------------------- -# lex(module) -# -# Build all of the regular expression rules from definitions in the supplied module -# ----------------------------------------------------------------------------- -def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,nowarn=0,outputdir="", debuglog=None, errorlog=None): - global lexer - ldict = None - stateinfo = { 'INITIAL' : 'inclusive'} - lexobj = Lexer() - lexobj.lexoptimize = optimize - global token,input - - if errorlog is None: - errorlog = PlyLogger(sys.stderr) - - if debug: - if debuglog is None: - debuglog = PlyLogger(sys.stderr) - - # Get the module dictionary used for the lexer - if object: module = object - - if module: - _items = [(k,getattr(module,k)) for k in dir(module)] - ldict = dict(_items) - else: - ldict = get_caller_module_dict(2) - - # Collect parser information from the dictionary - linfo = LexerReflect(ldict,log=errorlog,reflags=reflags) - linfo.get_all() - if not optimize: - if linfo.validate_all(): - raise SyntaxError("Can't build lexer") - - if optimize and lextab: - try: - lexobj.readtab(lextab,ldict) - token = lexobj.token - input = lexobj.input - lexer = lexobj - return lexobj - - except ImportError: - pass - - # Dump some basic debugging information - if debug: - debuglog.info("lex: tokens = %r", linfo.tokens) - debuglog.info("lex: literals = %r", linfo.literals) - debuglog.info("lex: states = %r", linfo.stateinfo) - - # Build a dictionary of valid token names - lexobj.lextokens = { } - for n in linfo.tokens: - lexobj.lextokens[n] = 1 - - # Get literals specification - if isinstance(linfo.literals,(list,tuple)): - lexobj.lexliterals = type(linfo.literals[0])().join(linfo.literals) - else: - lexobj.lexliterals = linfo.literals - - # Get the stateinfo dictionary - stateinfo = linfo.stateinfo - - regexs = { } - # Build the master regular expressions - for state in stateinfo: - regex_list = [] - - # Add rules defined by functions first - for fname, f in linfo.funcsym[state]: - line = func_code(f).co_firstlineno - file = func_code(f).co_filename - regex_list.append("(?P<%s>%s)" % (fname,f.__doc__)) - if debug: - debuglog.info("lex: Adding rule %s -> '%s' (state '%s')",fname,f.__doc__, state) - - # Now add all of the simple rules - for name,r in linfo.strsym[state]: - regex_list.append("(?P<%s>%s)" % (name,r)) - if debug: - debuglog.info("lex: Adding rule %s -> '%s' (state '%s')",name,r, state) - - regexs[state] = regex_list - - # Build the master regular expressions - - if debug: - debuglog.info("lex: ==== MASTER REGEXS FOLLOW ====") - - for state in regexs: - lexre, re_text, re_names = _form_master_re(regexs[state],reflags,ldict,linfo.toknames) - lexobj.lexstatere[state] = lexre - lexobj.lexstateretext[state] = re_text - lexobj.lexstaterenames[state] = re_names - if debug: - for i in range(len(re_text)): - debuglog.info("lex: state '%s' : regex[%d] = '%s'",state, i, re_text[i]) - - # For inclusive states, we need to add the regular expressions from the INITIAL state - for state,stype in stateinfo.items(): - if state != "INITIAL" and stype == 'inclusive': - lexobj.lexstatere[state].extend(lexobj.lexstatere['INITIAL']) - lexobj.lexstateretext[state].extend(lexobj.lexstateretext['INITIAL']) - lexobj.lexstaterenames[state].extend(lexobj.lexstaterenames['INITIAL']) - - lexobj.lexstateinfo = stateinfo - lexobj.lexre = lexobj.lexstatere["INITIAL"] - lexobj.lexretext = lexobj.lexstateretext["INITIAL"] - lexobj.lexreflags = reflags - - # Set up ignore variables - lexobj.lexstateignore = linfo.ignore - lexobj.lexignore = lexobj.lexstateignore.get("INITIAL","") - - # Set up error functions - lexobj.lexstateerrorf = linfo.errorf - lexobj.lexerrorf = linfo.errorf.get("INITIAL",None) - if not lexobj.lexerrorf: - errorlog.warning("No t_error rule is defined") - - # Check state information for ignore and error rules - for s,stype in stateinfo.items(): - if stype == 'exclusive': - if not s in linfo.errorf: - errorlog.warning("No error rule is defined for exclusive state '%s'", s) - if not s in linfo.ignore and lexobj.lexignore: - errorlog.warning("No ignore rule is defined for exclusive state '%s'", s) - elif stype == 'inclusive': - if not s in linfo.errorf: - linfo.errorf[s] = linfo.errorf.get("INITIAL",None) - if not s in linfo.ignore: - linfo.ignore[s] = linfo.ignore.get("INITIAL","") - - # Create global versions of the token() and input() functions - token = lexobj.token - input = lexobj.input - lexer = lexobj - - # If in optimize mode, we write the lextab - if lextab and optimize: - lexobj.writetab(lextab,outputdir) - - return lexobj - -# ----------------------------------------------------------------------------- -# runmain() -# -# This runs the lexer as a main program -# ----------------------------------------------------------------------------- - -def runmain(lexer=None,data=None): - if not data: - try: - filename = sys.argv[1] - f = open(filename) - data = f.read() - f.close() - except IndexError: - sys.stdout.write("Reading from standard input (type EOF to end):\n") - data = sys.stdin.read() - - if lexer: - _input = lexer.input - else: - _input = input - _input(data) - if lexer: - _token = lexer.token - else: - _token = token - - while 1: - tok = _token() - if not tok: break - sys.stdout.write("(%s,%r,%d,%d)\n" % (tok.type, tok.value, tok.lineno,tok.lexpos)) - -# ----------------------------------------------------------------------------- -# @TOKEN(regex) -# -# This decorator function can be used to set the regex expression on a function -# when its docstring might need to be set in an alternative way -# ----------------------------------------------------------------------------- - -def TOKEN(r): - def set_doc(f): - if hasattr(r,"__call__"): - f.__doc__ = r.__doc__ - else: - f.__doc__ = r - return f - return set_doc - -# Alternative spelling of the TOKEN decorator -Token = TOKEN - diff --git a/plugins_available/pycparser/pycparser/ply/yacc.py b/plugins_available/pycparser/pycparser/ply/yacc.py deleted file mode 100644 index 818de6d..0000000 --- a/plugins_available/pycparser/pycparser/ply/yacc.py +++ /dev/null @@ -1,3165 +0,0 @@ -# ----------------------------------------------------------------------------- -# ply: yacc.py -# -# Copyright (C) 2001-2009, -# David M. Beazley (Dabeaz LLC) -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of the David Beazley or Dabeaz LLC may be used to -# endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ----------------------------------------------------------------------------- -# -# This implements an LR parser that is constructed from grammar rules defined -# as Python functions. The grammer is specified by supplying the BNF inside -# Python documentation strings. The inspiration for this technique was borrowed -# from John Aycock's Spark parsing system. PLY might be viewed as cross between -# Spark and the GNU bison utility. -# -# The current implementation is only somewhat object-oriented. The -# LR parser itself is defined in terms of an object (which allows multiple -# parsers to co-exist). However, most of the variables used during table -# construction are defined in terms of global variables. Users shouldn't -# notice unless they are trying to define multiple parsers at the same -# time using threads (in which case they should have their head examined). -# -# This implementation supports both SLR and LALR(1) parsing. LALR(1) -# support was originally implemented by Elias Ioup (ezioup@alumni.uchicago.edu), -# using the algorithm found in Aho, Sethi, and Ullman "Compilers: Principles, -# Techniques, and Tools" (The Dragon Book). LALR(1) has since been replaced -# by the more efficient DeRemer and Pennello algorithm. -# -# :::::::: WARNING ::::::: -# -# Construction of LR parsing tables is fairly complicated and expensive. -# To make this module run fast, a *LOT* of work has been put into -# optimization---often at the expensive of readability and what might -# consider to be good Python "coding style." Modify the code at your -# own risk! -# ---------------------------------------------------------------------------- - -__version__ = "3.3" -__tabversion__ = "3.2" # Table version - -#----------------------------------------------------------------------------- -# === User configurable parameters === -# -# Change these to modify the default behavior of yacc (if you wish) -#----------------------------------------------------------------------------- - -yaccdebug = 1 # Debugging mode. If set, yacc generates a - # a 'parser.out' file in the current directory - -debug_file = 'parser.out' # Default name of the debugging file -tab_module = 'parsetab' # Default name of the table module -default_lr = 'LALR' # Default LR table generation method - -error_count = 3 # Number of symbols that must be shifted to leave recovery mode - -yaccdevel = 0 # Set to True if developing yacc. This turns off optimized - # implementations of certain functions. - -resultlimit = 40 # Size limit of results when running in debug mode. - -pickle_protocol = 0 # Protocol to use when writing pickle files - -import re, types, sys, os.path - -# Compatibility function for python 2.6/3.0 -if sys.version_info[0] < 3: - def func_code(f): - return f.func_code -else: - def func_code(f): - return f.__code__ - -# Compatibility -try: - MAXINT = sys.maxint -except AttributeError: - MAXINT = sys.maxsize - -# Python 2.x/3.0 compatibility. -def load_ply_lex(): - if sys.version_info[0] < 3: - import lex - else: - import ply.lex as lex - return lex - -# This object is a stand-in for a logging object created by the -# logging module. PLY will use this by default to create things -# such as the parser.out file. If a user wants more detailed -# information, they can create their own logging object and pass -# it into PLY. - -class PlyLogger(object): - def __init__(self,f): - self.f = f - def debug(self,msg,*args,**kwargs): - self.f.write((msg % args) + "\n") - info = debug - - def warning(self,msg,*args,**kwargs): - self.f.write("WARNING: "+ (msg % args) + "\n") - - def error(self,msg,*args,**kwargs): - self.f.write("ERROR: " + (msg % args) + "\n") - - critical = debug - -# Null logger is used when no output is generated. Does nothing. -class NullLogger(object): - def __getattribute__(self,name): - return self - def __call__(self,*args,**kwargs): - return self - -# Exception raised for yacc-related errors -class YaccError(Exception): pass - -# Format the result message that the parser produces when running in debug mode. -def format_result(r): - repr_str = repr(r) - if '\n' in repr_str: repr_str = repr(repr_str) - if len(repr_str) > resultlimit: - repr_str = repr_str[:resultlimit]+" ..." - result = "<%s @ 0x%x> (%s)" % (type(r).__name__,id(r),repr_str) - return result - - -# Format stack entries when the parser is running in debug mode -def format_stack_entry(r): - repr_str = repr(r) - if '\n' in repr_str: repr_str = repr(repr_str) - if len(repr_str) < 16: - return repr_str - else: - return "<%s @ 0x%x>" % (type(r).__name__,id(r)) - -#----------------------------------------------------------------------------- -# === LR Parsing Engine === -# -# The following classes are used for the LR parser itself. These are not -# used during table construction and are independent of the actual LR -# table generation algorithm -#----------------------------------------------------------------------------- - -# This class is used to hold non-terminal grammar symbols during parsing. -# It normally has the following attributes set: -# .type = Grammar symbol type -# .value = Symbol value -# .lineno = Starting line number -# .endlineno = Ending line number (optional, set automatically) -# .lexpos = Starting lex position -# .endlexpos = Ending lex position (optional, set automatically) - -class YaccSymbol: - def __str__(self): return self.type - def __repr__(self): return str(self) - -# This class is a wrapper around the objects actually passed to each -# grammar rule. Index lookup and assignment actually assign the -# .value attribute of the underlying YaccSymbol object. -# The lineno() method returns the line number of a given -# item (or 0 if not defined). The linespan() method returns -# a tuple of (startline,endline) representing the range of lines -# for a symbol. The lexspan() method returns a tuple (lexpos,endlexpos) -# representing the range of positional information for a symbol. - -class YaccProduction: - def __init__(self,s,stack=None): - self.slice = s - self.stack = stack - self.lexer = None - self.parser= None - def __getitem__(self,n): - if n >= 0: return self.slice[n].value - else: return self.stack[n].value - - def __setitem__(self,n,v): - self.slice[n].value = v - - def __getslice__(self,i,j): - return [s.value for s in self.slice[i:j]] - - def __len__(self): - return len(self.slice) - - def lineno(self,n): - return getattr(self.slice[n],"lineno",0) - - def set_lineno(self,n,lineno): - self.slice[n].lineno = lineno - - def linespan(self,n): - startline = getattr(self.slice[n],"lineno",0) - endline = getattr(self.slice[n],"endlineno",startline) - return startline,endline - - def lexpos(self,n): - return getattr(self.slice[n],"lexpos",0) - - def lexspan(self,n): - startpos = getattr(self.slice[n],"lexpos",0) - endpos = getattr(self.slice[n],"endlexpos",startpos) - return startpos,endpos - - def error(self): - raise SyntaxError - - -# ----------------------------------------------------------------------------- -# == LRParser == -# -# The LR Parsing engine. -# ----------------------------------------------------------------------------- - -class LRParser: - def __init__(self,lrtab,errorf): - self.productions = lrtab.lr_productions - self.action = lrtab.lr_action - self.goto = lrtab.lr_goto - self.errorfunc = errorf - - def errok(self): - self.errorok = 1 - - def restart(self): - del self.statestack[:] - del self.symstack[:] - sym = YaccSymbol() - sym.type = '$end' - self.symstack.append(sym) - self.statestack.append(0) - - def parse(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None): - if debug or yaccdevel: - if isinstance(debug,int): - debug = PlyLogger(sys.stderr) - return self.parsedebug(input,lexer,debug,tracking,tokenfunc) - elif tracking: - return self.parseopt(input,lexer,debug,tracking,tokenfunc) - else: - return self.parseopt_notrack(input,lexer,debug,tracking,tokenfunc) - - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # parsedebug(). - # - # This is the debugging enabled version of parse(). All changes made to the - # parsing engine should be made here. For the non-debugging version, - # copy this code to a method parseopt() and delete all of the sections - # enclosed in: - # - # #--! DEBUG - # statements - # #--! DEBUG - # - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - def parsedebug(self,input=None,lexer=None,debug=None,tracking=0,tokenfunc=None): - lookahead = None # Current lookahead symbol - lookaheadstack = [ ] # Stack of lookahead symbols - actions = self.action # Local reference to action table (to avoid lookup on self.) - goto = self.goto # Local reference to goto table (to avoid lookup on self.) - prod = self.productions # Local reference to production list (to avoid lookup on self.) - pslice = YaccProduction(None) # Production object passed to grammar rules - errorcount = 0 # Used during error recovery - - # --! DEBUG - debug.info("PLY: PARSE DEBUG START") - # --! DEBUG - - # If no lexer was given, we will try to use the lex module - if not lexer: - lex = load_ply_lex() - lexer = lex.lexer - - # Set up the lexer and parser objects on pslice - pslice.lexer = lexer - pslice.parser = self - - # If input was supplied, pass to lexer - if input is not None: - lexer.input(input) - - if tokenfunc is None: - # Tokenize function - get_token = lexer.token - else: - get_token = tokenfunc - - # Set up the state and symbol stacks - - statestack = [ ] # Stack of parsing states - self.statestack = statestack - symstack = [ ] # Stack of grammar symbols - self.symstack = symstack - - pslice.stack = symstack # Put in the production - errtoken = None # Err token - - # The start state is assumed to be (0,$end) - - statestack.append(0) - sym = YaccSymbol() - sym.type = "$end" - symstack.append(sym) - state = 0 - while 1: - # Get the next symbol on the input. If a lookahead symbol - # is already set, we just use that. Otherwise, we'll pull - # the next token off of the lookaheadstack or from the lexer - - # --! DEBUG - debug.debug('') - debug.debug('State : %s', state) - # --! DEBUG - - if not lookahead: - if not lookaheadstack: - lookahead = get_token() # Get the next token - else: - lookahead = lookaheadstack.pop() - if not lookahead: - lookahead = YaccSymbol() - lookahead.type = "$end" - - # --! DEBUG - debug.debug('Stack : %s', - ("%s . %s" % (" ".join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip()) - # --! DEBUG - - # Check the action table - ltype = lookahead.type - t = actions[state].get(ltype) - - if t is not None: - if t > 0: - # shift a symbol on the stack - statestack.append(t) - state = t - - # --! DEBUG - debug.debug("Action : Shift and goto state %s", t) - # --! DEBUG - - symstack.append(lookahead) - lookahead = None - - # Decrease error count on successful shift - if errorcount: errorcount -=1 - continue - - if t < 0: - # reduce a symbol on the stack, emit a production - p = prod[-t] - pname = p.name - plen = p.len - - # Get production function - sym = YaccSymbol() - sym.type = pname # Production name - sym.value = None - - # --! DEBUG - if plen: - debug.info("Action : Reduce rule [%s] with %s and goto state %d", p.str, "["+",".join([format_stack_entry(_v.value) for _v in symstack[-plen:]])+"]",-t) - else: - debug.info("Action : Reduce rule [%s] with %s and goto state %d", p.str, [],-t) - - # --! DEBUG - - if plen: - targ = symstack[-plen-1:] - targ[0] = sym - - # --! TRACKING - if tracking: - t1 = targ[1] - sym.lineno = t1.lineno - sym.lexpos = t1.lexpos - t1 = targ[-1] - sym.endlineno = getattr(t1,"endlineno",t1.lineno) - sym.endlexpos = getattr(t1,"endlexpos",t1.lexpos) - - # --! TRACKING - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # The code enclosed in this section is duplicated - # below as a performance optimization. Make sure - # changes get made in both locations. - - pslice.slice = targ - - try: - # Call the grammar rule with our special slice object - del symstack[-plen:] - del statestack[-plen:] - p.callable(pslice) - # --! DEBUG - debug.info("Result : %s", format_result(pslice[0])) - # --! DEBUG - symstack.append(sym) - state = goto[statestack[-1]][pname] - statestack.append(state) - except SyntaxError: - # If an error was set. Enter error recovery state - lookaheadstack.append(lookahead) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - continue - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - else: - - # --! TRACKING - if tracking: - sym.lineno = lexer.lineno - sym.lexpos = lexer.lexpos - # --! TRACKING - - targ = [ sym ] - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # The code enclosed in this section is duplicated - # above as a performance optimization. Make sure - # changes get made in both locations. - - pslice.slice = targ - - try: - # Call the grammar rule with our special slice object - p.callable(pslice) - # --! DEBUG - debug.info("Result : %s", format_result(pslice[0])) - # --! DEBUG - symstack.append(sym) - state = goto[statestack[-1]][pname] - statestack.append(state) - except SyntaxError: - # If an error was set. Enter error recovery state - lookaheadstack.append(lookahead) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - continue - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - if t == 0: - n = symstack[-1] - result = getattr(n,"value",None) - # --! DEBUG - debug.info("Done : Returning %s", format_result(result)) - debug.info("PLY: PARSE DEBUG END") - # --! DEBUG - return result - - if t == None: - - # --! DEBUG - debug.error('Error : %s', - ("%s . %s" % (" ".join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip()) - # --! DEBUG - - # We have some kind of parsing error here. To handle - # this, we are going to push the current token onto - # the tokenstack and replace it with an 'error' token. - # If there are any synchronization rules, they may - # catch it. - # - # In addition to pushing the error token, we call call - # the user defined p_error() function if this is the - # first syntax error. This function is only called if - # errorcount == 0. - if errorcount == 0 or self.errorok: - errorcount = error_count - self.errorok = 0 - errtoken = lookahead - if errtoken.type == "$end": - errtoken = None # End of file! - if self.errorfunc: - global errok,token,restart - errok = self.errok # Set some special functions available in error recovery - token = get_token - restart = self.restart - if errtoken and not hasattr(errtoken,'lexer'): - errtoken.lexer = lexer - tok = self.errorfunc(errtoken) - del errok, token, restart # Delete special functions - - if self.errorok: - # User must have done some kind of panic - # mode recovery on their own. The - # returned token is the next lookahead - lookahead = tok - errtoken = None - continue - else: - if errtoken: - if hasattr(errtoken,"lineno"): lineno = lookahead.lineno - else: lineno = 0 - if lineno: - sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type)) - else: - sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type) - else: - sys.stderr.write("yacc: Parse error in input. EOF\n") - return - - else: - errorcount = error_count - - # case 1: the statestack only has 1 entry on it. If we're in this state, the - # entire parse has been rolled back and we're completely hosed. The token is - # discarded and we just keep going. - - if len(statestack) <= 1 and lookahead.type != "$end": - lookahead = None - errtoken = None - state = 0 - # Nuke the pushback stack - del lookaheadstack[:] - continue - - # case 2: the statestack has a couple of entries on it, but we're - # at the end of the file. nuke the top entry and generate an error token - - # Start nuking entries on the stack - if lookahead.type == "$end": - # Whoa. We're really hosed here. Bail out - return - - if lookahead.type != 'error': - sym = symstack[-1] - if sym.type == 'error': - # Hmmm. Error is on top of stack, we'll just nuke input - # symbol and continue - lookahead = None - continue - t = YaccSymbol() - t.type = 'error' - if hasattr(lookahead,"lineno"): - t.lineno = lookahead.lineno - t.value = lookahead - lookaheadstack.append(lookahead) - lookahead = t - else: - symstack.pop() - statestack.pop() - state = statestack[-1] # Potential bug fix - - continue - - # Call an error function here - raise RuntimeError("yacc: internal parser error!!!\n") - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # parseopt(). - # - # Optimized version of parse() method. DO NOT EDIT THIS CODE DIRECTLY. - # Edit the debug version above, then copy any modifications to the method - # below while removing #--! DEBUG sections. - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - - def parseopt(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None): - lookahead = None # Current lookahead symbol - lookaheadstack = [ ] # Stack of lookahead symbols - actions = self.action # Local reference to action table (to avoid lookup on self.) - goto = self.goto # Local reference to goto table (to avoid lookup on self.) - prod = self.productions # Local reference to production list (to avoid lookup on self.) - pslice = YaccProduction(None) # Production object passed to grammar rules - errorcount = 0 # Used during error recovery - - # If no lexer was given, we will try to use the lex module - if not lexer: - lex = load_ply_lex() - lexer = lex.lexer - - # Set up the lexer and parser objects on pslice - pslice.lexer = lexer - pslice.parser = self - - # If input was supplied, pass to lexer - if input is not None: - lexer.input(input) - - if tokenfunc is None: - # Tokenize function - get_token = lexer.token - else: - get_token = tokenfunc - - # Set up the state and symbol stacks - - statestack = [ ] # Stack of parsing states - self.statestack = statestack - symstack = [ ] # Stack of grammar symbols - self.symstack = symstack - - pslice.stack = symstack # Put in the production - errtoken = None # Err token - - # The start state is assumed to be (0,$end) - - statestack.append(0) - sym = YaccSymbol() - sym.type = '$end' - symstack.append(sym) - state = 0 - while 1: - # Get the next symbol on the input. If a lookahead symbol - # is already set, we just use that. Otherwise, we'll pull - # the next token off of the lookaheadstack or from the lexer - - if not lookahead: - if not lookaheadstack: - lookahead = get_token() # Get the next token - else: - lookahead = lookaheadstack.pop() - if not lookahead: - lookahead = YaccSymbol() - lookahead.type = '$end' - - # Check the action table - ltype = lookahead.type - t = actions[state].get(ltype) - - if t is not None: - if t > 0: - # shift a symbol on the stack - statestack.append(t) - state = t - - symstack.append(lookahead) - lookahead = None - - # Decrease error count on successful shift - if errorcount: errorcount -=1 - continue - - if t < 0: - # reduce a symbol on the stack, emit a production - p = prod[-t] - pname = p.name - plen = p.len - - # Get production function - sym = YaccSymbol() - sym.type = pname # Production name - sym.value = None - - if plen: - targ = symstack[-plen-1:] - targ[0] = sym - - # --! TRACKING - if tracking: - t1 = targ[1] - sym.lineno = t1.lineno - sym.lexpos = t1.lexpos - t1 = targ[-1] - sym.endlineno = getattr(t1,"endlineno",t1.lineno) - sym.endlexpos = getattr(t1,"endlexpos",t1.lexpos) - - # --! TRACKING - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # The code enclosed in this section is duplicated - # below as a performance optimization. Make sure - # changes get made in both locations. - - pslice.slice = targ - - try: - # Call the grammar rule with our special slice object - del symstack[-plen:] - del statestack[-plen:] - p.callable(pslice) - symstack.append(sym) - state = goto[statestack[-1]][pname] - statestack.append(state) - except SyntaxError: - # If an error was set. Enter error recovery state - lookaheadstack.append(lookahead) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - continue - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - else: - - # --! TRACKING - if tracking: - sym.lineno = lexer.lineno - sym.lexpos = lexer.lexpos - # --! TRACKING - - targ = [ sym ] - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # The code enclosed in this section is duplicated - # above as a performance optimization. Make sure - # changes get made in both locations. - - pslice.slice = targ - - try: - # Call the grammar rule with our special slice object - p.callable(pslice) - symstack.append(sym) - state = goto[statestack[-1]][pname] - statestack.append(state) - except SyntaxError: - # If an error was set. Enter error recovery state - lookaheadstack.append(lookahead) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - continue - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - if t == 0: - n = symstack[-1] - return getattr(n,"value",None) - - if t == None: - - # We have some kind of parsing error here. To handle - # this, we are going to push the current token onto - # the tokenstack and replace it with an 'error' token. - # If there are any synchronization rules, they may - # catch it. - # - # In addition to pushing the error token, we call call - # the user defined p_error() function if this is the - # first syntax error. This function is only called if - # errorcount == 0. - if errorcount == 0 or self.errorok: - errorcount = error_count - self.errorok = 0 - errtoken = lookahead - if errtoken.type == '$end': - errtoken = None # End of file! - if self.errorfunc: - global errok,token,restart - errok = self.errok # Set some special functions available in error recovery - token = get_token - restart = self.restart - if errtoken and not hasattr(errtoken,'lexer'): - errtoken.lexer = lexer - tok = self.errorfunc(errtoken) - del errok, token, restart # Delete special functions - - if self.errorok: - # User must have done some kind of panic - # mode recovery on their own. The - # returned token is the next lookahead - lookahead = tok - errtoken = None - continue - else: - if errtoken: - if hasattr(errtoken,"lineno"): lineno = lookahead.lineno - else: lineno = 0 - if lineno: - sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type)) - else: - sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type) - else: - sys.stderr.write("yacc: Parse error in input. EOF\n") - return - - else: - errorcount = error_count - - # case 1: the statestack only has 1 entry on it. If we're in this state, the - # entire parse has been rolled back and we're completely hosed. The token is - # discarded and we just keep going. - - if len(statestack) <= 1 and lookahead.type != '$end': - lookahead = None - errtoken = None - state = 0 - # Nuke the pushback stack - del lookaheadstack[:] - continue - - # case 2: the statestack has a couple of entries on it, but we're - # at the end of the file. nuke the top entry and generate an error token - - # Start nuking entries on the stack - if lookahead.type == '$end': - # Whoa. We're really hosed here. Bail out - return - - if lookahead.type != 'error': - sym = symstack[-1] - if sym.type == 'error': - # Hmmm. Error is on top of stack, we'll just nuke input - # symbol and continue - lookahead = None - continue - t = YaccSymbol() - t.type = 'error' - if hasattr(lookahead,"lineno"): - t.lineno = lookahead.lineno - t.value = lookahead - lookaheadstack.append(lookahead) - lookahead = t - else: - symstack.pop() - statestack.pop() - state = statestack[-1] # Potential bug fix - - continue - - # Call an error function here - raise RuntimeError("yacc: internal parser error!!!\n") - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # parseopt_notrack(). - # - # Optimized version of parseopt() with line number tracking removed. - # DO NOT EDIT THIS CODE DIRECTLY. Copy the optimized version and remove - # code in the #--! TRACKING sections - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - def parseopt_notrack(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None): - lookahead = None # Current lookahead symbol - lookaheadstack = [ ] # Stack of lookahead symbols - actions = self.action # Local reference to action table (to avoid lookup on self.) - goto = self.goto # Local reference to goto table (to avoid lookup on self.) - prod = self.productions # Local reference to production list (to avoid lookup on self.) - pslice = YaccProduction(None) # Production object passed to grammar rules - errorcount = 0 # Used during error recovery - - # If no lexer was given, we will try to use the lex module - if not lexer: - lex = load_ply_lex() - lexer = lex.lexer - - # Set up the lexer and parser objects on pslice - pslice.lexer = lexer - pslice.parser = self - - # If input was supplied, pass to lexer - if input is not None: - lexer.input(input) - - if tokenfunc is None: - # Tokenize function - get_token = lexer.token - else: - get_token = tokenfunc - - # Set up the state and symbol stacks - - statestack = [ ] # Stack of parsing states - self.statestack = statestack - symstack = [ ] # Stack of grammar symbols - self.symstack = symstack - - pslice.stack = symstack # Put in the production - errtoken = None # Err token - - # The start state is assumed to be (0,$end) - - statestack.append(0) - sym = YaccSymbol() - sym.type = '$end' - symstack.append(sym) - state = 0 - while 1: - # Get the next symbol on the input. If a lookahead symbol - # is already set, we just use that. Otherwise, we'll pull - # the next token off of the lookaheadstack or from the lexer - - if not lookahead: - if not lookaheadstack: - lookahead = get_token() # Get the next token - else: - lookahead = lookaheadstack.pop() - if not lookahead: - lookahead = YaccSymbol() - lookahead.type = '$end' - - # Check the action table - ltype = lookahead.type - t = actions[state].get(ltype) - - if t is not None: - if t > 0: - # shift a symbol on the stack - statestack.append(t) - state = t - - symstack.append(lookahead) - lookahead = None - - # Decrease error count on successful shift - if errorcount: errorcount -=1 - continue - - if t < 0: - # reduce a symbol on the stack, emit a production - p = prod[-t] - pname = p.name - plen = p.len - - # Get production function - sym = YaccSymbol() - sym.type = pname # Production name - sym.value = None - - if plen: - targ = symstack[-plen-1:] - targ[0] = sym - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # The code enclosed in this section is duplicated - # below as a performance optimization. Make sure - # changes get made in both locations. - - pslice.slice = targ - - try: - # Call the grammar rule with our special slice object - del symstack[-plen:] - del statestack[-plen:] - p.callable(pslice) - symstack.append(sym) - state = goto[statestack[-1]][pname] - statestack.append(state) - except SyntaxError: - # If an error was set. Enter error recovery state - lookaheadstack.append(lookahead) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - continue - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - else: - - targ = [ sym ] - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # The code enclosed in this section is duplicated - # above as a performance optimization. Make sure - # changes get made in both locations. - - pslice.slice = targ - - try: - # Call the grammar rule with our special slice object - p.callable(pslice) - symstack.append(sym) - state = goto[statestack[-1]][pname] - statestack.append(state) - except SyntaxError: - # If an error was set. Enter error recovery state - lookaheadstack.append(lookahead) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - continue - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - if t == 0: - n = symstack[-1] - return getattr(n,"value",None) - - if t == None: - - # We have some kind of parsing error here. To handle - # this, we are going to push the current token onto - # the tokenstack and replace it with an 'error' token. - # If there are any synchronization rules, they may - # catch it. - # - # In addition to pushing the error token, we call call - # the user defined p_error() function if this is the - # first syntax error. This function is only called if - # errorcount == 0. - if errorcount == 0 or self.errorok: - errorcount = error_count - self.errorok = 0 - errtoken = lookahead - if errtoken.type == '$end': - errtoken = None # End of file! - if self.errorfunc: - global errok,token,restart - errok = self.errok # Set some special functions available in error recovery - token = get_token - restart = self.restart - if errtoken and not hasattr(errtoken,'lexer'): - errtoken.lexer = lexer - tok = self.errorfunc(errtoken) - del errok, token, restart # Delete special functions - - if self.errorok: - # User must have done some kind of panic - # mode recovery on their own. The - # returned token is the next lookahead - lookahead = tok - errtoken = None - continue - else: - if errtoken: - if hasattr(errtoken,"lineno"): lineno = lookahead.lineno - else: lineno = 0 - if lineno: - sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type)) - else: - sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type) - else: - sys.stderr.write("yacc: Parse error in input. EOF\n") - return - - else: - errorcount = error_count - - # case 1: the statestack only has 1 entry on it. If we're in this state, the - # entire parse has been rolled back and we're completely hosed. The token is - # discarded and we just keep going. - - if len(statestack) <= 1 and lookahead.type != '$end': - lookahead = None - errtoken = None - state = 0 - # Nuke the pushback stack - del lookaheadstack[:] - continue - - # case 2: the statestack has a couple of entries on it, but we're - # at the end of the file. nuke the top entry and generate an error token - - # Start nuking entries on the stack - if lookahead.type == '$end': - # Whoa. We're really hosed here. Bail out - return - - if lookahead.type != 'error': - sym = symstack[-1] - if sym.type == 'error': - # Hmmm. Error is on top of stack, we'll just nuke input - # symbol and continue - lookahead = None - continue - t = YaccSymbol() - t.type = 'error' - if hasattr(lookahead,"lineno"): - t.lineno = lookahead.lineno - t.value = lookahead - lookaheadstack.append(lookahead) - lookahead = t - else: - symstack.pop() - statestack.pop() - state = statestack[-1] # Potential bug fix - - continue - - # Call an error function here - raise RuntimeError("yacc: internal parser error!!!\n") - -# ----------------------------------------------------------------------------- -# === Grammar Representation === -# -# The following functions, classes, and variables are used to represent and -# manipulate the rules that make up a grammar. -# ----------------------------------------------------------------------------- - -import re - -# regex matching identifiers -_is_identifier = re.compile(r'^[a-zA-Z0-9_-]+$') - -# ----------------------------------------------------------------------------- -# class Production: -# -# This class stores the raw information about a single production or grammar rule. -# A grammar rule refers to a specification such as this: -# -# expr : expr PLUS term -# -# Here are the basic attributes defined on all productions -# -# name - Name of the production. For example 'expr' -# prod - A list of symbols on the right side ['expr','PLUS','term'] -# prec - Production precedence level -# number - Production number. -# func - Function that executes on reduce -# file - File where production function is defined -# lineno - Line number where production function is defined -# -# The following attributes are defined or optional. -# -# len - Length of the production (number of symbols on right hand side) -# usyms - Set of unique symbols found in the production -# ----------------------------------------------------------------------------- - -class Production(object): - reduced = 0 - def __init__(self,number,name,prod,precedence=('right',0),func=None,file='',line=0): - self.name = name - self.prod = tuple(prod) - self.number = number - self.func = func - self.callable = None - self.file = file - self.line = line - self.prec = precedence - - # Internal settings used during table construction - - self.len = len(self.prod) # Length of the production - - # Create a list of unique production symbols used in the production - self.usyms = [ ] - for s in self.prod: - if s not in self.usyms: - self.usyms.append(s) - - # List of all LR items for the production - self.lr_items = [] - self.lr_next = None - - # Create a string representation - if self.prod: - self.str = "%s -> %s" % (self.name," ".join(self.prod)) - else: - self.str = "%s -> " % self.name - - def __str__(self): - return self.str - - def __repr__(self): - return "Production("+str(self)+")" - - def __len__(self): - return len(self.prod) - - def __nonzero__(self): - return 1 - - def __getitem__(self,index): - return self.prod[index] - - # Return the nth lr_item from the production (or None if at the end) - def lr_item(self,n): - if n > len(self.prod): return None - p = LRItem(self,n) - - # Precompute the list of productions immediately following. Hack. Remove later - try: - p.lr_after = Prodnames[p.prod[n+1]] - except (IndexError,KeyError): - p.lr_after = [] - try: - p.lr_before = p.prod[n-1] - except IndexError: - p.lr_before = None - - return p - - # Bind the production function name to a callable - def bind(self,pdict): - if self.func: - self.callable = pdict[self.func] - -# This class serves as a minimal standin for Production objects when -# reading table data from files. It only contains information -# actually used by the LR parsing engine, plus some additional -# debugging information. -class MiniProduction(object): - def __init__(self,str,name,len,func,file,line): - self.name = name - self.len = len - self.func = func - self.callable = None - self.file = file - self.line = line - self.str = str - def __str__(self): - return self.str - def __repr__(self): - return "MiniProduction(%s)" % self.str - - # Bind the production function name to a callable - def bind(self,pdict): - if self.func: - self.callable = pdict[self.func] - - -# ----------------------------------------------------------------------------- -# class LRItem -# -# This class represents a specific stage of parsing a production rule. For -# example: -# -# expr : expr . PLUS term -# -# In the above, the "." represents the current location of the parse. Here -# basic attributes: -# -# name - Name of the production. For example 'expr' -# prod - A list of symbols on the right side ['expr','.', 'PLUS','term'] -# number - Production number. -# -# lr_next Next LR item. Example, if we are ' expr -> expr . PLUS term' -# then lr_next refers to 'expr -> expr PLUS . term' -# lr_index - LR item index (location of the ".") in the prod list. -# lookaheads - LALR lookahead symbols for this item -# len - Length of the production (number of symbols on right hand side) -# lr_after - List of all productions that immediately follow -# lr_before - Grammar symbol immediately before -# ----------------------------------------------------------------------------- - -class LRItem(object): - def __init__(self,p,n): - self.name = p.name - self.prod = list(p.prod) - self.number = p.number - self.lr_index = n - self.lookaheads = { } - self.prod.insert(n,".") - self.prod = tuple(self.prod) - self.len = len(self.prod) - self.usyms = p.usyms - - def __str__(self): - if self.prod: - s = "%s -> %s" % (self.name," ".join(self.prod)) - else: - s = "%s -> " % self.name - return s - - def __repr__(self): - return "LRItem("+str(self)+")" - -# ----------------------------------------------------------------------------- -# rightmost_terminal() -# -# Return the rightmost terminal from a list of symbols. Used in add_production() -# ----------------------------------------------------------------------------- -def rightmost_terminal(symbols, terminals): - i = len(symbols) - 1 - while i >= 0: - if symbols[i] in terminals: - return symbols[i] - i -= 1 - return None - -# ----------------------------------------------------------------------------- -# === GRAMMAR CLASS === -# -# The following class represents the contents of the specified grammar along -# with various computed properties such as first sets, follow sets, LR items, etc. -# This data is used for critical parts of the table generation process later. -# ----------------------------------------------------------------------------- - -class GrammarError(YaccError): pass - -class Grammar(object): - def __init__(self,terminals): - self.Productions = [None] # A list of all of the productions. The first - # entry is always reserved for the purpose of - # building an augmented grammar - - self.Prodnames = { } # A dictionary mapping the names of nonterminals to a list of all - # productions of that nonterminal. - - self.Prodmap = { } # A dictionary that is only used to detect duplicate - # productions. - - self.Terminals = { } # A dictionary mapping the names of terminal symbols to a - # list of the rules where they are used. - - for term in terminals: - self.Terminals[term] = [] - - self.Terminals['error'] = [] - - self.Nonterminals = { } # A dictionary mapping names of nonterminals to a list - # of rule numbers where they are used. - - self.First = { } # A dictionary of precomputed FIRST(x) symbols - - self.Follow = { } # A dictionary of precomputed FOLLOW(x) symbols - - self.Precedence = { } # Precedence rules for each terminal. Contains tuples of the - # form ('right',level) or ('nonassoc', level) or ('left',level) - - self.UsedPrecedence = { } # Precedence rules that were actually used by the grammer. - # This is only used to provide error checking and to generate - # a warning about unused precedence rules. - - self.Start = None # Starting symbol for the grammar - - - def __len__(self): - return len(self.Productions) - - def __getitem__(self,index): - return self.Productions[index] - - # ----------------------------------------------------------------------------- - # set_precedence() - # - # Sets the precedence for a given terminal. assoc is the associativity such as - # 'left','right', or 'nonassoc'. level is a numeric level. - # - # ----------------------------------------------------------------------------- - - def set_precedence(self,term,assoc,level): - assert self.Productions == [None],"Must call set_precedence() before add_production()" - if term in self.Precedence: - raise GrammarError("Precedence already specified for terminal '%s'" % term) - if assoc not in ['left','right','nonassoc']: - raise GrammarError("Associativity must be one of 'left','right', or 'nonassoc'") - self.Precedence[term] = (assoc,level) - - # ----------------------------------------------------------------------------- - # add_production() - # - # Given an action function, this function assembles a production rule and - # computes its precedence level. - # - # The production rule is supplied as a list of symbols. For example, - # a rule such as 'expr : expr PLUS term' has a production name of 'expr' and - # symbols ['expr','PLUS','term']. - # - # Precedence is determined by the precedence of the right-most non-terminal - # or the precedence of a terminal specified by %prec. - # - # A variety of error checks are performed to make sure production symbols - # are valid and that %prec is used correctly. - # ----------------------------------------------------------------------------- - - def add_production(self,prodname,syms,func=None,file='',line=0): - - if prodname in self.Terminals: - raise GrammarError("%s:%d: Illegal rule name '%s'. Already defined as a token" % (file,line,prodname)) - if prodname == 'error': - raise GrammarError("%s:%d: Illegal rule name '%s'. error is a reserved word" % (file,line,prodname)) - if not _is_identifier.match(prodname): - raise GrammarError("%s:%d: Illegal rule name '%s'" % (file,line,prodname)) - - # Look for literal tokens - for n,s in enumerate(syms): - if s[0] in "'\"": - try: - c = eval(s) - if (len(c) > 1): - raise GrammarError("%s:%d: Literal token %s in rule '%s' may only be a single character" % (file,line,s, prodname)) - if not c in self.Terminals: - self.Terminals[c] = [] - syms[n] = c - continue - except SyntaxError: - pass - if not _is_identifier.match(s) and s != '%prec': - raise GrammarError("%s:%d: Illegal name '%s' in rule '%s'" % (file,line,s, prodname)) - - # Determine the precedence level - if '%prec' in syms: - if syms[-1] == '%prec': - raise GrammarError("%s:%d: Syntax error. Nothing follows %%prec" % (file,line)) - if syms[-2] != '%prec': - raise GrammarError("%s:%d: Syntax error. %%prec can only appear at the end of a grammar rule" % (file,line)) - precname = syms[-1] - prodprec = self.Precedence.get(precname,None) - if not prodprec: - raise GrammarError("%s:%d: Nothing known about the precedence of '%s'" % (file,line,precname)) - else: - self.UsedPrecedence[precname] = 1 - del syms[-2:] # Drop %prec from the rule - else: - # If no %prec, precedence is determined by the rightmost terminal symbol - precname = rightmost_terminal(syms,self.Terminals) - prodprec = self.Precedence.get(precname,('right',0)) - - # See if the rule is already in the rulemap - map = "%s -> %s" % (prodname,syms) - if map in self.Prodmap: - m = self.Prodmap[map] - raise GrammarError("%s:%d: Duplicate rule %s. " % (file,line, m) + - "Previous definition at %s:%d" % (m.file, m.line)) - - # From this point on, everything is valid. Create a new Production instance - pnumber = len(self.Productions) - if not prodname in self.Nonterminals: - self.Nonterminals[prodname] = [ ] - - # Add the production number to Terminals and Nonterminals - for t in syms: - if t in self.Terminals: - self.Terminals[t].append(pnumber) - else: - if not t in self.Nonterminals: - self.Nonterminals[t] = [ ] - self.Nonterminals[t].append(pnumber) - - # Create a production and add it to the list of productions - p = Production(pnumber,prodname,syms,prodprec,func,file,line) - self.Productions.append(p) - self.Prodmap[map] = p - - # Add to the global productions list - try: - self.Prodnames[prodname].append(p) - except KeyError: - self.Prodnames[prodname] = [ p ] - return 0 - - # ----------------------------------------------------------------------------- - # set_start() - # - # Sets the starting symbol and creates the augmented grammar. Production - # rule 0 is S' -> start where start is the start symbol. - # ----------------------------------------------------------------------------- - - def set_start(self,start=None): - if not start: - start = self.Productions[1].name - if start not in self.Nonterminals: - raise GrammarError("start symbol %s undefined" % start) - self.Productions[0] = Production(0,"S'",[start]) - self.Nonterminals[start].append(0) - self.Start = start - - # ----------------------------------------------------------------------------- - # find_unreachable() - # - # Find all of the nonterminal symbols that can't be reached from the starting - # symbol. Returns a list of nonterminals that can't be reached. - # ----------------------------------------------------------------------------- - - def find_unreachable(self): - - # Mark all symbols that are reachable from a symbol s - def mark_reachable_from(s): - if reachable[s]: - # We've already reached symbol s. - return - reachable[s] = 1 - for p in self.Prodnames.get(s,[]): - for r in p.prod: - mark_reachable_from(r) - - reachable = { } - for s in list(self.Terminals) + list(self.Nonterminals): - reachable[s] = 0 - - mark_reachable_from( self.Productions[0].prod[0] ) - - return [s for s in list(self.Nonterminals) - if not reachable[s]] - - # ----------------------------------------------------------------------------- - # infinite_cycles() - # - # This function looks at the various parsing rules and tries to detect - # infinite recursion cycles (grammar rules where there is no possible way - # to derive a string of only terminals). - # ----------------------------------------------------------------------------- - - def infinite_cycles(self): - terminates = {} - - # Terminals: - for t in self.Terminals: - terminates[t] = 1 - - terminates['$end'] = 1 - - # Nonterminals: - - # Initialize to false: - for n in self.Nonterminals: - terminates[n] = 0 - - # Then propagate termination until no change: - while 1: - some_change = 0 - for (n,pl) in self.Prodnames.items(): - # Nonterminal n terminates iff any of its productions terminates. - for p in pl: - # Production p terminates iff all of its rhs symbols terminate. - for s in p.prod: - if not terminates[s]: - # The symbol s does not terminate, - # so production p does not terminate. - p_terminates = 0 - break - else: - # didn't break from the loop, - # so every symbol s terminates - # so production p terminates. - p_terminates = 1 - - if p_terminates: - # symbol n terminates! - if not terminates[n]: - terminates[n] = 1 - some_change = 1 - # Don't need to consider any more productions for this n. - break - - if not some_change: - break - - infinite = [] - for (s,term) in terminates.items(): - if not term: - if not s in self.Prodnames and not s in self.Terminals and s != 'error': - # s is used-but-not-defined, and we've already warned of that, - # so it would be overkill to say that it's also non-terminating. - pass - else: - infinite.append(s) - - return infinite - - - # ----------------------------------------------------------------------------- - # undefined_symbols() - # - # Find all symbols that were used the grammar, but not defined as tokens or - # grammar rules. Returns a list of tuples (sym, prod) where sym in the symbol - # and prod is the production where the symbol was used. - # ----------------------------------------------------------------------------- - def undefined_symbols(self): - result = [] - for p in self.Productions: - if not p: continue - - for s in p.prod: - if not s in self.Prodnames and not s in self.Terminals and s != 'error': - result.append((s,p)) - return result - - # ----------------------------------------------------------------------------- - # unused_terminals() - # - # Find all terminals that were defined, but not used by the grammar. Returns - # a list of all symbols. - # ----------------------------------------------------------------------------- - def unused_terminals(self): - unused_tok = [] - for s,v in self.Terminals.items(): - if s != 'error' and not v: - unused_tok.append(s) - - return unused_tok - - # ------------------------------------------------------------------------------ - # unused_rules() - # - # Find all grammar rules that were defined, but not used (maybe not reachable) - # Returns a list of productions. - # ------------------------------------------------------------------------------ - - def unused_rules(self): - unused_prod = [] - for s,v in self.Nonterminals.items(): - if not v: - p = self.Prodnames[s][0] - unused_prod.append(p) - return unused_prod - - # ----------------------------------------------------------------------------- - # unused_precedence() - # - # Returns a list of tuples (term,precedence) corresponding to precedence - # rules that were never used by the grammar. term is the name of the terminal - # on which precedence was applied and precedence is a string such as 'left' or - # 'right' corresponding to the type of precedence. - # ----------------------------------------------------------------------------- - - def unused_precedence(self): - unused = [] - for termname in self.Precedence: - if not (termname in self.Terminals or termname in self.UsedPrecedence): - unused.append((termname,self.Precedence[termname][0])) - - return unused - - # ------------------------------------------------------------------------- - # _first() - # - # Compute the value of FIRST1(beta) where beta is a tuple of symbols. - # - # During execution of compute_first1, the result may be incomplete. - # Afterward (e.g., when called from compute_follow()), it will be complete. - # ------------------------------------------------------------------------- - def _first(self,beta): - - # We are computing First(x1,x2,x3,...,xn) - result = [ ] - for x in beta: - x_produces_empty = 0 - - # Add all the non- symbols of First[x] to the result. - for f in self.First[x]: - if f == '': - x_produces_empty = 1 - else: - if f not in result: result.append(f) - - if x_produces_empty: - # We have to consider the next x in beta, - # i.e. stay in the loop. - pass - else: - # We don't have to consider any further symbols in beta. - break - else: - # There was no 'break' from the loop, - # so x_produces_empty was true for all x in beta, - # so beta produces empty as well. - result.append('') - - return result - - # ------------------------------------------------------------------------- - # compute_first() - # - # Compute the value of FIRST1(X) for all symbols - # ------------------------------------------------------------------------- - def compute_first(self): - if self.First: - return self.First - - # Terminals: - for t in self.Terminals: - self.First[t] = [t] - - self.First['$end'] = ['$end'] - - # Nonterminals: - - # Initialize to the empty set: - for n in self.Nonterminals: - self.First[n] = [] - - # Then propagate symbols until no change: - while 1: - some_change = 0 - for n in self.Nonterminals: - for p in self.Prodnames[n]: - for f in self._first(p.prod): - if f not in self.First[n]: - self.First[n].append( f ) - some_change = 1 - if not some_change: - break - - return self.First - - # --------------------------------------------------------------------- - # compute_follow() - # - # Computes all of the follow sets for every non-terminal symbol. The - # follow set is the set of all symbols that might follow a given - # non-terminal. See the Dragon book, 2nd Ed. p. 189. - # --------------------------------------------------------------------- - def compute_follow(self,start=None): - # If already computed, return the result - if self.Follow: - return self.Follow - - # If first sets not computed yet, do that first. - if not self.First: - self.compute_first() - - # Add '$end' to the follow list of the start symbol - for k in self.Nonterminals: - self.Follow[k] = [ ] - - if not start: - start = self.Productions[1].name - - self.Follow[start] = [ '$end' ] - - while 1: - didadd = 0 - for p in self.Productions[1:]: - # Here is the production set - for i in range(len(p.prod)): - B = p.prod[i] - if B in self.Nonterminals: - # Okay. We got a non-terminal in a production - fst = self._first(p.prod[i+1:]) - hasempty = 0 - for f in fst: - if f != '' and f not in self.Follow[B]: - self.Follow[B].append(f) - didadd = 1 - if f == '': - hasempty = 1 - if hasempty or i == (len(p.prod)-1): - # Add elements of follow(a) to follow(b) - for f in self.Follow[p.name]: - if f not in self.Follow[B]: - self.Follow[B].append(f) - didadd = 1 - if not didadd: break - return self.Follow - - - # ----------------------------------------------------------------------------- - # build_lritems() - # - # This function walks the list of productions and builds a complete set of the - # LR items. The LR items are stored in two ways: First, they are uniquely - # numbered and placed in the list _lritems. Second, a linked list of LR items - # is built for each production. For example: - # - # E -> E PLUS E - # - # Creates the list - # - # [E -> . E PLUS E, E -> E . PLUS E, E -> E PLUS . E, E -> E PLUS E . ] - # ----------------------------------------------------------------------------- - - def build_lritems(self): - for p in self.Productions: - lastlri = p - i = 0 - lr_items = [] - while 1: - if i > len(p): - lri = None - else: - lri = LRItem(p,i) - # Precompute the list of productions immediately following - try: - lri.lr_after = self.Prodnames[lri.prod[i+1]] - except (IndexError,KeyError): - lri.lr_after = [] - try: - lri.lr_before = lri.prod[i-1] - except IndexError: - lri.lr_before = None - - lastlri.lr_next = lri - if not lri: break - lr_items.append(lri) - lastlri = lri - i += 1 - p.lr_items = lr_items - -# ----------------------------------------------------------------------------- -# == Class LRTable == -# -# This basic class represents a basic table of LR parsing information. -# Methods for generating the tables are not defined here. They are defined -# in the derived class LRGeneratedTable. -# ----------------------------------------------------------------------------- - -class VersionError(YaccError): pass - -class LRTable(object): - def __init__(self): - self.lr_action = None - self.lr_goto = None - self.lr_productions = None - self.lr_method = None - - def read_table(self,module): - if isinstance(module,types.ModuleType): - parsetab = module - else: - if sys.version_info[0] < 3: - exec("import %s as parsetab" % module) - else: - env = { } - exec("import %s as parsetab" % module, env, env) - parsetab = env['parsetab'] - - if parsetab._tabversion != __tabversion__: - raise VersionError("yacc table file version is out of date") - - self.lr_action = parsetab._lr_action - self.lr_goto = parsetab._lr_goto - - self.lr_productions = [] - for p in parsetab._lr_productions: - self.lr_productions.append(MiniProduction(*p)) - - self.lr_method = parsetab._lr_method - return parsetab._lr_signature - - def read_pickle(self,filename): - try: - import cPickle as pickle - except ImportError: - import pickle - - in_f = open(filename,"rb") - - tabversion = pickle.load(in_f) - if tabversion != __tabversion__: - raise VersionError("yacc table file version is out of date") - self.lr_method = pickle.load(in_f) - signature = pickle.load(in_f) - self.lr_action = pickle.load(in_f) - self.lr_goto = pickle.load(in_f) - productions = pickle.load(in_f) - - self.lr_productions = [] - for p in productions: - self.lr_productions.append(MiniProduction(*p)) - - in_f.close() - return signature - - # Bind all production function names to callable objects in pdict - def bind_callables(self,pdict): - for p in self.lr_productions: - p.bind(pdict) - -# ----------------------------------------------------------------------------- -# === LR Generator === -# -# The following classes and functions are used to generate LR parsing tables on -# a grammar. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# digraph() -# traverse() -# -# The following two functions are used to compute set valued functions -# of the form: -# -# F(x) = F'(x) U U{F(y) | x R y} -# -# This is used to compute the values of Read() sets as well as FOLLOW sets -# in LALR(1) generation. -# -# Inputs: X - An input set -# R - A relation -# FP - Set-valued function -# ------------------------------------------------------------------------------ - -def digraph(X,R,FP): - N = { } - for x in X: - N[x] = 0 - stack = [] - F = { } - for x in X: - if N[x] == 0: traverse(x,N,stack,F,X,R,FP) - return F - -def traverse(x,N,stack,F,X,R,FP): - stack.append(x) - d = len(stack) - N[x] = d - F[x] = FP(x) # F(X) <- F'(x) - - rel = R(x) # Get y's related to x - for y in rel: - if N[y] == 0: - traverse(y,N,stack,F,X,R,FP) - N[x] = min(N[x],N[y]) - for a in F.get(y,[]): - if a not in F[x]: F[x].append(a) - if N[x] == d: - N[stack[-1]] = MAXINT - F[stack[-1]] = F[x] - element = stack.pop() - while element != x: - N[stack[-1]] = MAXINT - F[stack[-1]] = F[x] - element = stack.pop() - -class LALRError(YaccError): pass - -# ----------------------------------------------------------------------------- -# == LRGeneratedTable == -# -# This class implements the LR table generation algorithm. There are no -# public methods except for write() -# ----------------------------------------------------------------------------- - -class LRGeneratedTable(LRTable): - def __init__(self,grammar,method='LALR',log=None): - if method not in ['SLR','LALR']: - raise LALRError("Unsupported method %s" % method) - - self.grammar = grammar - self.lr_method = method - - # Set up the logger - if not log: - log = NullLogger() - self.log = log - - # Internal attributes - self.lr_action = {} # Action table - self.lr_goto = {} # Goto table - self.lr_productions = grammar.Productions # Copy of grammar Production array - self.lr_goto_cache = {} # Cache of computed gotos - self.lr0_cidhash = {} # Cache of closures - - self._add_count = 0 # Internal counter used to detect cycles - - # Diagonistic information filled in by the table generator - self.sr_conflict = 0 - self.rr_conflict = 0 - self.conflicts = [] # List of conflicts - - self.sr_conflicts = [] - self.rr_conflicts = [] - - # Build the tables - self.grammar.build_lritems() - self.grammar.compute_first() - self.grammar.compute_follow() - self.lr_parse_table() - - # Compute the LR(0) closure operation on I, where I is a set of LR(0) items. - - def lr0_closure(self,I): - self._add_count += 1 - - # Add everything in I to J - J = I[:] - didadd = 1 - while didadd: - didadd = 0 - for j in J: - for x in j.lr_after: - if getattr(x,"lr0_added",0) == self._add_count: continue - # Add B --> .G to J - J.append(x.lr_next) - x.lr0_added = self._add_count - didadd = 1 - - return J - - # Compute the LR(0) goto function goto(I,X) where I is a set - # of LR(0) items and X is a grammar symbol. This function is written - # in a way that guarantees uniqueness of the generated goto sets - # (i.e. the same goto set will never be returned as two different Python - # objects). With uniqueness, we can later do fast set comparisons using - # id(obj) instead of element-wise comparison. - - def lr0_goto(self,I,x): - # First we look for a previously cached entry - g = self.lr_goto_cache.get((id(I),x),None) - if g: return g - - # Now we generate the goto set in a way that guarantees uniqueness - # of the result - - s = self.lr_goto_cache.get(x,None) - if not s: - s = { } - self.lr_goto_cache[x] = s - - gs = [ ] - for p in I: - n = p.lr_next - if n and n.lr_before == x: - s1 = s.get(id(n),None) - if not s1: - s1 = { } - s[id(n)] = s1 - gs.append(n) - s = s1 - g = s.get('$end',None) - if not g: - if gs: - g = self.lr0_closure(gs) - s['$end'] = g - else: - s['$end'] = gs - self.lr_goto_cache[(id(I),x)] = g - return g - - # Compute the LR(0) sets of item function - def lr0_items(self): - - C = [ self.lr0_closure([self.grammar.Productions[0].lr_next]) ] - i = 0 - for I in C: - self.lr0_cidhash[id(I)] = i - i += 1 - - # Loop over the items in C and each grammar symbols - i = 0 - while i < len(C): - I = C[i] - i += 1 - - # Collect all of the symbols that could possibly be in the goto(I,X) sets - asyms = { } - for ii in I: - for s in ii.usyms: - asyms[s] = None - - for x in asyms: - g = self.lr0_goto(I,x) - if not g: continue - if id(g) in self.lr0_cidhash: continue - self.lr0_cidhash[id(g)] = len(C) - C.append(g) - - return C - - # ----------------------------------------------------------------------------- - # ==== LALR(1) Parsing ==== - # - # LALR(1) parsing is almost exactly the same as SLR except that instead of - # relying upon Follow() sets when performing reductions, a more selective - # lookahead set that incorporates the state of the LR(0) machine is utilized. - # Thus, we mainly just have to focus on calculating the lookahead sets. - # - # The method used here is due to DeRemer and Pennelo (1982). - # - # DeRemer, F. L., and T. J. Pennelo: "Efficient Computation of LALR(1) - # Lookahead Sets", ACM Transactions on Programming Languages and Systems, - # Vol. 4, No. 4, Oct. 1982, pp. 615-649 - # - # Further details can also be found in: - # - # J. Tremblay and P. Sorenson, "The Theory and Practice of Compiler Writing", - # McGraw-Hill Book Company, (1985). - # - # ----------------------------------------------------------------------------- - - # ----------------------------------------------------------------------------- - # compute_nullable_nonterminals() - # - # Creates a dictionary containing all of the non-terminals that might produce - # an empty production. - # ----------------------------------------------------------------------------- - - def compute_nullable_nonterminals(self): - nullable = {} - num_nullable = 0 - while 1: - for p in self.grammar.Productions[1:]: - if p.len == 0: - nullable[p.name] = 1 - continue - for t in p.prod: - if not t in nullable: break - else: - nullable[p.name] = 1 - if len(nullable) == num_nullable: break - num_nullable = len(nullable) - return nullable - - # ----------------------------------------------------------------------------- - # find_nonterminal_trans(C) - # - # Given a set of LR(0) items, this functions finds all of the non-terminal - # transitions. These are transitions in which a dot appears immediately before - # a non-terminal. Returns a list of tuples of the form (state,N) where state - # is the state number and N is the nonterminal symbol. - # - # The input C is the set of LR(0) items. - # ----------------------------------------------------------------------------- - - def find_nonterminal_transitions(self,C): - trans = [] - for state in range(len(C)): - for p in C[state]: - if p.lr_index < p.len - 1: - t = (state,p.prod[p.lr_index+1]) - if t[1] in self.grammar.Nonterminals: - if t not in trans: trans.append(t) - state = state + 1 - return trans - - # ----------------------------------------------------------------------------- - # dr_relation() - # - # Computes the DR(p,A) relationships for non-terminal transitions. The input - # is a tuple (state,N) where state is a number and N is a nonterminal symbol. - # - # Returns a list of terminals. - # ----------------------------------------------------------------------------- - - def dr_relation(self,C,trans,nullable): - dr_set = { } - state,N = trans - terms = [] - - g = self.lr0_goto(C[state],N) - for p in g: - if p.lr_index < p.len - 1: - a = p.prod[p.lr_index+1] - if a in self.grammar.Terminals: - if a not in terms: terms.append(a) - - # This extra bit is to handle the start state - if state == 0 and N == self.grammar.Productions[0].prod[0]: - terms.append('$end') - - return terms - - # ----------------------------------------------------------------------------- - # reads_relation() - # - # Computes the READS() relation (p,A) READS (t,C). - # ----------------------------------------------------------------------------- - - def reads_relation(self,C, trans, empty): - # Look for empty transitions - rel = [] - state, N = trans - - g = self.lr0_goto(C[state],N) - j = self.lr0_cidhash.get(id(g),-1) - for p in g: - if p.lr_index < p.len - 1: - a = p.prod[p.lr_index + 1] - if a in empty: - rel.append((j,a)) - - return rel - - # ----------------------------------------------------------------------------- - # compute_lookback_includes() - # - # Determines the lookback and includes relations - # - # LOOKBACK: - # - # This relation is determined by running the LR(0) state machine forward. - # For example, starting with a production "N : . A B C", we run it forward - # to obtain "N : A B C ." We then build a relationship between this final - # state and the starting state. These relationships are stored in a dictionary - # lookdict. - # - # INCLUDES: - # - # Computes the INCLUDE() relation (p,A) INCLUDES (p',B). - # - # This relation is used to determine non-terminal transitions that occur - # inside of other non-terminal transition states. (p,A) INCLUDES (p', B) - # if the following holds: - # - # B -> LAT, where T -> epsilon and p' -L-> p - # - # L is essentially a prefix (which may be empty), T is a suffix that must be - # able to derive an empty string. State p' must lead to state p with the string L. - # - # ----------------------------------------------------------------------------- - - def compute_lookback_includes(self,C,trans,nullable): - - lookdict = {} # Dictionary of lookback relations - includedict = {} # Dictionary of include relations - - # Make a dictionary of non-terminal transitions - dtrans = {} - for t in trans: - dtrans[t] = 1 - - # Loop over all transitions and compute lookbacks and includes - for state,N in trans: - lookb = [] - includes = [] - for p in C[state]: - if p.name != N: continue - - # Okay, we have a name match. We now follow the production all the way - # through the state machine until we get the . on the right hand side - - lr_index = p.lr_index - j = state - while lr_index < p.len - 1: - lr_index = lr_index + 1 - t = p.prod[lr_index] - - # Check to see if this symbol and state are a non-terminal transition - if (j,t) in dtrans: - # Yes. Okay, there is some chance that this is an includes relation - # the only way to know for certain is whether the rest of the - # production derives empty - - li = lr_index + 1 - while li < p.len: - if p.prod[li] in self.grammar.Terminals: break # No forget it - if not p.prod[li] in nullable: break - li = li + 1 - else: - # Appears to be a relation between (j,t) and (state,N) - includes.append((j,t)) - - g = self.lr0_goto(C[j],t) # Go to next set - j = self.lr0_cidhash.get(id(g),-1) # Go to next state - - # When we get here, j is the final state, now we have to locate the production - for r in C[j]: - if r.name != p.name: continue - if r.len != p.len: continue - i = 0 - # This look is comparing a production ". A B C" with "A B C ." - while i < r.lr_index: - if r.prod[i] != p.prod[i+1]: break - i = i + 1 - else: - lookb.append((j,r)) - for i in includes: - if not i in includedict: includedict[i] = [] - includedict[i].append((state,N)) - lookdict[(state,N)] = lookb - - return lookdict,includedict - - # ----------------------------------------------------------------------------- - # compute_read_sets() - # - # Given a set of LR(0) items, this function computes the read sets. - # - # Inputs: C = Set of LR(0) items - # ntrans = Set of nonterminal transitions - # nullable = Set of empty transitions - # - # Returns a set containing the read sets - # ----------------------------------------------------------------------------- - - def compute_read_sets(self,C, ntrans, nullable): - FP = lambda x: self.dr_relation(C,x,nullable) - R = lambda x: self.reads_relation(C,x,nullable) - F = digraph(ntrans,R,FP) - return F - - # ----------------------------------------------------------------------------- - # compute_follow_sets() - # - # Given a set of LR(0) items, a set of non-terminal transitions, a readset, - # and an include set, this function computes the follow sets - # - # Follow(p,A) = Read(p,A) U U {Follow(p',B) | (p,A) INCLUDES (p',B)} - # - # Inputs: - # ntrans = Set of nonterminal transitions - # readsets = Readset (previously computed) - # inclsets = Include sets (previously computed) - # - # Returns a set containing the follow sets - # ----------------------------------------------------------------------------- - - def compute_follow_sets(self,ntrans,readsets,inclsets): - FP = lambda x: readsets[x] - R = lambda x: inclsets.get(x,[]) - F = digraph(ntrans,R,FP) - return F - - # ----------------------------------------------------------------------------- - # add_lookaheads() - # - # Attaches the lookahead symbols to grammar rules. - # - # Inputs: lookbacks - Set of lookback relations - # followset - Computed follow set - # - # This function directly attaches the lookaheads to productions contained - # in the lookbacks set - # ----------------------------------------------------------------------------- - - def add_lookaheads(self,lookbacks,followset): - for trans,lb in lookbacks.items(): - # Loop over productions in lookback - for state,p in lb: - if not state in p.lookaheads: - p.lookaheads[state] = [] - f = followset.get(trans,[]) - for a in f: - if a not in p.lookaheads[state]: p.lookaheads[state].append(a) - - # ----------------------------------------------------------------------------- - # add_lalr_lookaheads() - # - # This function does all of the work of adding lookahead information for use - # with LALR parsing - # ----------------------------------------------------------------------------- - - def add_lalr_lookaheads(self,C): - # Determine all of the nullable nonterminals - nullable = self.compute_nullable_nonterminals() - - # Find all non-terminal transitions - trans = self.find_nonterminal_transitions(C) - - # Compute read sets - readsets = self.compute_read_sets(C,trans,nullable) - - # Compute lookback/includes relations - lookd, included = self.compute_lookback_includes(C,trans,nullable) - - # Compute LALR FOLLOW sets - followsets = self.compute_follow_sets(trans,readsets,included) - - # Add all of the lookaheads - self.add_lookaheads(lookd,followsets) - - # ----------------------------------------------------------------------------- - # lr_parse_table() - # - # This function constructs the parse tables for SLR or LALR - # ----------------------------------------------------------------------------- - def lr_parse_table(self): - Productions = self.grammar.Productions - Precedence = self.grammar.Precedence - goto = self.lr_goto # Goto array - action = self.lr_action # Action array - log = self.log # Logger for output - - actionp = { } # Action production array (temporary) - - log.info("Parsing method: %s", self.lr_method) - - # Step 1: Construct C = { I0, I1, ... IN}, collection of LR(0) items - # This determines the number of states - - C = self.lr0_items() - - if self.lr_method == 'LALR': - self.add_lalr_lookaheads(C) - - # Build the parser table, state by state - st = 0 - for I in C: - # Loop over each production in I - actlist = [ ] # List of actions - st_action = { } - st_actionp = { } - st_goto = { } - log.info("") - log.info("state %d", st) - log.info("") - for p in I: - log.info(" (%d) %s", p.number, str(p)) - log.info("") - - for p in I: - if p.len == p.lr_index + 1: - if p.name == "S'": - # Start symbol. Accept! - st_action["$end"] = 0 - st_actionp["$end"] = p - else: - # We are at the end of a production. Reduce! - if self.lr_method == 'LALR': - laheads = p.lookaheads[st] - else: - laheads = self.grammar.Follow[p.name] - for a in laheads: - actlist.append((a,p,"reduce using rule %d (%s)" % (p.number,p))) - r = st_action.get(a,None) - if r is not None: - # Whoa. Have a shift/reduce or reduce/reduce conflict - if r > 0: - # Need to decide on shift or reduce here - # By default we favor shifting. Need to add - # some precedence rules here. - sprec,slevel = Productions[st_actionp[a].number].prec - rprec,rlevel = Precedence.get(a,('right',0)) - if (slevel < rlevel) or ((slevel == rlevel) and (rprec == 'left')): - # We really need to reduce here. - st_action[a] = -p.number - st_actionp[a] = p - if not slevel and not rlevel: - log.info(" ! shift/reduce conflict for %s resolved as reduce",a) - self.sr_conflicts.append((st,a,'reduce')) - Productions[p.number].reduced += 1 - elif (slevel == rlevel) and (rprec == 'nonassoc'): - st_action[a] = None - else: - # Hmmm. Guess we'll keep the shift - if not rlevel: - log.info(" ! shift/reduce conflict for %s resolved as shift",a) - self.sr_conflicts.append((st,a,'shift')) - elif r < 0: - # Reduce/reduce conflict. In this case, we favor the rule - # that was defined first in the grammar file - oldp = Productions[-r] - pp = Productions[p.number] - if oldp.line > pp.line: - st_action[a] = -p.number - st_actionp[a] = p - chosenp,rejectp = pp,oldp - Productions[p.number].reduced += 1 - Productions[oldp.number].reduced -= 1 - else: - chosenp,rejectp = oldp,pp - self.rr_conflicts.append((st,chosenp,rejectp)) - log.info(" ! reduce/reduce conflict for %s resolved using rule %d (%s)", a,st_actionp[a].number, st_actionp[a]) - else: - raise LALRError("Unknown conflict in state %d" % st) - else: - st_action[a] = -p.number - st_actionp[a] = p - Productions[p.number].reduced += 1 - else: - i = p.lr_index - a = p.prod[i+1] # Get symbol right after the "." - if a in self.grammar.Terminals: - g = self.lr0_goto(I,a) - j = self.lr0_cidhash.get(id(g),-1) - if j >= 0: - # We are in a shift state - actlist.append((a,p,"shift and go to state %d" % j)) - r = st_action.get(a,None) - if r is not None: - # Whoa have a shift/reduce or shift/shift conflict - if r > 0: - if r != j: - raise LALRError("Shift/shift conflict in state %d" % st) - elif r < 0: - # Do a precedence check. - # - if precedence of reduce rule is higher, we reduce. - # - if precedence of reduce is same and left assoc, we reduce. - # - otherwise we shift - rprec,rlevel = Productions[st_actionp[a].number].prec - sprec,slevel = Precedence.get(a,('right',0)) - if (slevel > rlevel) or ((slevel == rlevel) and (rprec == 'right')): - # We decide to shift here... highest precedence to shift - Productions[st_actionp[a].number].reduced -= 1 - st_action[a] = j - st_actionp[a] = p - if not rlevel: - log.info(" ! shift/reduce conflict for %s resolved as shift",a) - self.sr_conflicts.append((st,a,'shift')) - elif (slevel == rlevel) and (rprec == 'nonassoc'): - st_action[a] = None - else: - # Hmmm. Guess we'll keep the reduce - if not slevel and not rlevel: - log.info(" ! shift/reduce conflict for %s resolved as reduce",a) - self.sr_conflicts.append((st,a,'reduce')) - - else: - raise LALRError("Unknown conflict in state %d" % st) - else: - st_action[a] = j - st_actionp[a] = p - - # Print the actions associated with each terminal - _actprint = { } - for a,p,m in actlist: - if a in st_action: - if p is st_actionp[a]: - log.info(" %-15s %s",a,m) - _actprint[(a,m)] = 1 - log.info("") - # Print the actions that were not used. (debugging) - not_used = 0 - for a,p,m in actlist: - if a in st_action: - if p is not st_actionp[a]: - if not (a,m) in _actprint: - log.debug(" ! %-15s [ %s ]",a,m) - not_used = 1 - _actprint[(a,m)] = 1 - if not_used: - log.debug("") - - # Construct the goto table for this state - - nkeys = { } - for ii in I: - for s in ii.usyms: - if s in self.grammar.Nonterminals: - nkeys[s] = None - for n in nkeys: - g = self.lr0_goto(I,n) - j = self.lr0_cidhash.get(id(g),-1) - if j >= 0: - st_goto[n] = j - log.info(" %-30s shift and go to state %d",n,j) - - action[st] = st_action - actionp[st] = st_actionp - goto[st] = st_goto - st += 1 - - - # ----------------------------------------------------------------------------- - # write() - # - # This function writes the LR parsing tables to a file - # ----------------------------------------------------------------------------- - - def write_table(self,modulename,outputdir='',signature=""): - return - - - # ----------------------------------------------------------------------------- - # pickle_table() - # - # This function pickles the LR parsing tables to a supplied file object - # ----------------------------------------------------------------------------- - - def pickle_table(self,filename,signature=""): - try: - import cPickle as pickle - except ImportError: - import pickle - outf = open(filename,"wb") - pickle.dump(__tabversion__,outf,pickle_protocol) - pickle.dump(self.lr_method,outf,pickle_protocol) - pickle.dump(signature,outf,pickle_protocol) - pickle.dump(self.lr_action,outf,pickle_protocol) - pickle.dump(self.lr_goto,outf,pickle_protocol) - - outp = [] - for p in self.lr_productions: - if p.func: - outp.append((p.str,p.name, p.len, p.func,p.file,p.line)) - else: - outp.append((str(p),p.name,p.len,None,None,None)) - pickle.dump(outp,outf,pickle_protocol) - outf.close() - -# ----------------------------------------------------------------------------- -# === INTROSPECTION === -# -# The following functions and classes are used to implement the PLY -# introspection features followed by the yacc() function itself. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# get_caller_module_dict() -# -# This function returns a dictionary containing all of the symbols defined within -# a caller further down the call stack. This is used to get the environment -# associated with the yacc() call if none was provided. -# ----------------------------------------------------------------------------- - -def get_caller_module_dict(levels): - try: - raise RuntimeError - except RuntimeError: - e,b,t = sys.exc_info() - f = t.tb_frame - while levels > 0: - f = f.f_back - levels -= 1 - ldict = f.f_globals.copy() - if f.f_globals != f.f_locals: - ldict.update(f.f_locals) - - return ldict - -# ----------------------------------------------------------------------------- -# parse_grammar() -# -# This takes a raw grammar rule string and parses it into production data -# ----------------------------------------------------------------------------- -def parse_grammar(doc,file,line): - grammar = [] - # Split the doc string into lines - pstrings = doc.splitlines() - lastp = None - dline = line - for ps in pstrings: - dline += 1 - p = ps.split() - if not p: continue - try: - if p[0] == '|': - # This is a continuation of a previous rule - if not lastp: - raise SyntaxError("%s:%d: Misplaced '|'" % (file,dline)) - prodname = lastp - syms = p[1:] - else: - prodname = p[0] - lastp = prodname - syms = p[2:] - assign = p[1] - if assign != ':' and assign != '::=': - raise SyntaxError("%s:%d: Syntax error. Expected ':'" % (file,dline)) - - grammar.append((file,dline,prodname,syms)) - except SyntaxError: - raise - except Exception: - raise SyntaxError("%s:%d: Syntax error in rule '%s'" % (file,dline,ps.strip())) - - return grammar - -# ----------------------------------------------------------------------------- -# ParserReflect() -# -# This class represents information extracted for building a parser including -# start symbol, error function, tokens, precedence list, action functions, -# etc. -# ----------------------------------------------------------------------------- -class ParserReflect(object): - def __init__(self,pdict,log=None): - self.pdict = pdict - self.start = None - self.error_func = None - self.tokens = None - self.files = {} - self.grammar = [] - self.error = 0 - - if log is None: - self.log = PlyLogger(sys.stderr) - else: - self.log = log - - # Get all of the basic information - def get_all(self): - self.get_start() - self.get_error_func() - self.get_tokens() - self.get_precedence() - self.get_pfunctions() - - # Validate all of the information - def validate_all(self): - self.validate_start() - self.validate_error_func() - self.validate_tokens() - self.validate_precedence() - self.validate_pfunctions() - self.validate_files() - return self.error - - # Compute a signature over the grammar - def signature(self): - try: - from hashlib import md5 - except ImportError: - from md5 import md5 - try: - sig = md5() - if self.start: - sig.update(self.start.encode('latin-1')) - if self.prec: - sig.update("".join(["".join(p) for p in self.prec]).encode('latin-1')) - if self.tokens: - sig.update(" ".join(self.tokens).encode('latin-1')) - for f in self.pfuncs: - if f[3]: - sig.update(f[3].encode('latin-1')) - except (TypeError,ValueError): - pass - return sig.digest() - - # ----------------------------------------------------------------------------- - # validate_file() - # - # This method checks to see if there are duplicated p_rulename() functions - # in the parser module file. Without this function, it is really easy for - # users to make mistakes by cutting and pasting code fragments (and it's a real - # bugger to try and figure out why the resulting parser doesn't work). Therefore, - # we just do a little regular expression pattern matching of def statements - # to try and detect duplicates. - # ----------------------------------------------------------------------------- - - def validate_files(self): - # Match def p_funcname( - fre = re.compile(r'\s*def\s+(p_[a-zA-Z_0-9]*)\(') - - for filename in self.files.keys(): - base,ext = os.path.splitext(filename) - if ext != '.py': return 1 # No idea. Assume it's okay. - - try: - f = open(filename) - lines = f.readlines() - f.close() - except IOError: - continue - - counthash = { } - for linen,l in enumerate(lines): - linen += 1 - m = fre.match(l) - if m: - name = m.group(1) - prev = counthash.get(name) - if not prev: - counthash[name] = linen - else: - self.log.warning("%s:%d: Function %s redefined. Previously defined on line %d", filename,linen,name,prev) - - # Get the start symbol - def get_start(self): - self.start = self.pdict.get('start') - - # Validate the start symbol - def validate_start(self): - if self.start is not None: - if not isinstance(self.start,str): - self.log.error("'start' must be a string") - - # Look for error handler - def get_error_func(self): - self.error_func = self.pdict.get('p_error') - - # Validate the error function - def validate_error_func(self): - if self.error_func: - if isinstance(self.error_func,types.FunctionType): - ismethod = 0 - elif isinstance(self.error_func, types.MethodType): - ismethod = 1 - else: - self.log.error("'p_error' defined, but is not a function or method") - self.error = 1 - return - - eline = func_code(self.error_func).co_firstlineno - efile = func_code(self.error_func).co_filename - self.files[efile] = 1 - - if (func_code(self.error_func).co_argcount != 1+ismethod): - self.log.error("%s:%d: p_error() requires 1 argument",efile,eline) - self.error = 1 - - # Get the tokens map - def get_tokens(self): - tokens = self.pdict.get("tokens",None) - if not tokens: - self.log.error("No token list is defined") - self.error = 1 - return - - if not isinstance(tokens,(list, tuple)): - self.log.error("tokens must be a list or tuple") - self.error = 1 - return - - if not tokens: - self.log.error("tokens is empty") - self.error = 1 - return - - self.tokens = tokens - - # Validate the tokens - def validate_tokens(self): - # Validate the tokens. - if 'error' in self.tokens: - self.log.error("Illegal token name 'error'. Is a reserved word") - self.error = 1 - return - - terminals = {} - for n in self.tokens: - if n in terminals: - self.log.warning("Token '%s' multiply defined", n) - terminals[n] = 1 - - # Get the precedence map (if any) - def get_precedence(self): - self.prec = self.pdict.get("precedence",None) - - # Validate and parse the precedence map - def validate_precedence(self): - preclist = [] - if self.prec: - if not isinstance(self.prec,(list,tuple)): - self.log.error("precedence must be a list or tuple") - self.error = 1 - return - for level,p in enumerate(self.prec): - if not isinstance(p,(list,tuple)): - self.log.error("Bad precedence table") - self.error = 1 - return - - if len(p) < 2: - self.log.error("Malformed precedence entry %s. Must be (assoc, term, ..., term)",p) - self.error = 1 - return - assoc = p[0] - if not isinstance(assoc,str): - self.log.error("precedence associativity must be a string") - self.error = 1 - return - for term in p[1:]: - if not isinstance(term,str): - self.log.error("precedence items must be strings") - self.error = 1 - return - preclist.append((term,assoc,level+1)) - self.preclist = preclist - - # Get all p_functions from the grammar - def get_pfunctions(self): - p_functions = [] - for name, item in self.pdict.items(): - if name[:2] != 'p_': continue - if name == 'p_error': continue - if isinstance(item,(types.FunctionType,types.MethodType)): - line = func_code(item).co_firstlineno - file = func_code(item).co_filename - p_functions.append((line,file,name,item.__doc__)) - - # Sort all of the actions by line number - p_functions.sort() - self.pfuncs = p_functions - - - # Validate all of the p_functions - def validate_pfunctions(self): - grammar = [] - # Check for non-empty symbols - if len(self.pfuncs) == 0: - self.log.error("no rules of the form p_rulename are defined") - self.error = 1 - return - - for line, file, name, doc in self.pfuncs: - func = self.pdict[name] - if isinstance(func, types.MethodType): - reqargs = 2 - else: - reqargs = 1 - if func_code(func).co_argcount > reqargs: - self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,func.__name__) - self.error = 1 - elif func_code(func).co_argcount < reqargs: - self.log.error("%s:%d: Rule '%s' requires an argument",file,line,func.__name__) - self.error = 1 - elif not func.__doc__: - self.log.warning("%s:%d: No documentation string specified in function '%s' (ignored)",file,line,func.__name__) - else: - try: - parsed_g = parse_grammar(doc,file,line) - for g in parsed_g: - grammar.append((name, g)) - except SyntaxError: - e = sys.exc_info()[1] - self.log.error(str(e)) - self.error = 1 - - # Looks like a valid grammar rule - # Mark the file in which defined. - self.files[file] = 1 - - # Secondary validation step that looks for p_ definitions that are not functions - # or functions that look like they might be grammar rules. - - for n,v in self.pdict.items(): - if n[0:2] == 'p_' and isinstance(v, (types.FunctionType, types.MethodType)): continue - if n[0:2] == 't_': continue - if n[0:2] == 'p_' and n != 'p_error': - self.log.warning("'%s' not defined as a function", n) - if ((isinstance(v,types.FunctionType) and func_code(v).co_argcount == 1) or - (isinstance(v,types.MethodType) and func_code(v).co_argcount == 2)): - try: - doc = v.__doc__.split(" ") - if doc[1] == ':': - self.log.warning("%s:%d: Possible grammar rule '%s' defined without p_ prefix", - func_code(v).co_filename, func_code(v).co_firstlineno,n) - except Exception: - pass - - self.grammar = grammar - -# ----------------------------------------------------------------------------- -# yacc(module) -# -# Build a parser -# ----------------------------------------------------------------------------- - -def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, start=None, - check_recursion=1, optimize=0, write_tables=1, debugfile=debug_file,outputdir='', - debuglog=None, errorlog = None, picklefile=None): - - global parse # Reference to the parsing method of the last built parser - - # If pickling is enabled, table files are not created - - if picklefile: - write_tables = 0 - - if errorlog is None: - errorlog = PlyLogger(sys.stderr) - - # Get the module dictionary used for the parser - if module: - _items = [(k,getattr(module,k)) for k in dir(module)] - pdict = dict(_items) - else: - pdict = get_caller_module_dict(2) - - # Collect parser information from the dictionary - pinfo = ParserReflect(pdict,log=errorlog) - pinfo.get_all() - - if pinfo.error: - raise YaccError("Unable to build parser") - - # Check signature against table files (if any) - signature = pinfo.signature() - - # Read the tables - try: - lr = LRTable() - if picklefile: - read_signature = lr.read_pickle(picklefile) - else: - read_signature = lr.read_table(tabmodule) - if optimize or (read_signature == signature): - try: - lr.bind_callables(pinfo.pdict) - parser = LRParser(lr,pinfo.error_func) - parse = parser.parse - return parser - except Exception: - e = sys.exc_info()[1] - errorlog.warning("There was a problem loading the table file: %s", repr(e)) - except VersionError: - e = sys.exc_info() - errorlog.warning(str(e)) - except Exception: - pass - - if debuglog is None: - if debug: - debuglog = PlyLogger(open(debugfile,"w")) - else: - debuglog = NullLogger() - - debuglog.info("Created by PLY version %s (http://www.dabeaz.com/ply)", __version__) - - - errors = 0 - - # Validate the parser information - if pinfo.validate_all(): - raise YaccError("Unable to build parser") - - if not pinfo.error_func: - errorlog.warning("no p_error() function is defined") - - # Create a grammar object - grammar = Grammar(pinfo.tokens) - - # Set precedence level for terminals - for term, assoc, level in pinfo.preclist: - try: - grammar.set_precedence(term,assoc,level) - except GrammarError: - e = sys.exc_info()[1] - errorlog.warning("%s",str(e)) - - # Add productions to the grammar - for funcname, gram in pinfo.grammar: - file, line, prodname, syms = gram - try: - grammar.add_production(prodname,syms,funcname,file,line) - except GrammarError: - e = sys.exc_info()[1] - errorlog.error("%s",str(e)) - errors = 1 - - # Set the grammar start symbols - try: - if start is None: - grammar.set_start(pinfo.start) - else: - grammar.set_start(start) - except GrammarError: - e = sys.exc_info()[1] - errorlog.error(str(e)) - errors = 1 - - if errors: - raise YaccError("Unable to build parser") - - # Verify the grammar structure - undefined_symbols = grammar.undefined_symbols() - for sym, prod in undefined_symbols: - errorlog.error("%s:%d: Symbol '%s' used, but not defined as a token or a rule",prod.file,prod.line,sym) - errors = 1 - - unused_terminals = grammar.unused_terminals() - if unused_terminals: - debuglog.info("") - debuglog.info("Unused terminals:") - debuglog.info("") - for term in unused_terminals: - errorlog.warning("Token '%s' defined, but not used", term) - debuglog.info(" %s", term) - - # Print out all productions to the debug log - if debug: - debuglog.info("") - debuglog.info("Grammar") - debuglog.info("") - for n,p in enumerate(grammar.Productions): - debuglog.info("Rule %-5d %s", n, p) - - # Find unused non-terminals - unused_rules = grammar.unused_rules() - for prod in unused_rules: - errorlog.warning("%s:%d: Rule '%s' defined, but not used", prod.file, prod.line, prod.name) - - if len(unused_terminals) == 1: - errorlog.warning("There is 1 unused token") - if len(unused_terminals) > 1: - errorlog.warning("There are %d unused tokens", len(unused_terminals)) - - if len(unused_rules) == 1: - errorlog.warning("There is 1 unused rule") - if len(unused_rules) > 1: - errorlog.warning("There are %d unused rules", len(unused_rules)) - - if debug: - debuglog.info("") - debuglog.info("Terminals, with rules where they appear") - debuglog.info("") - terms = list(grammar.Terminals) - terms.sort() - for term in terms: - debuglog.info("%-20s : %s", term, " ".join([str(s) for s in grammar.Terminals[term]])) - - debuglog.info("") - debuglog.info("Nonterminals, with rules where they appear") - debuglog.info("") - nonterms = list(grammar.Nonterminals) - nonterms.sort() - for nonterm in nonterms: - debuglog.info("%-20s : %s", nonterm, " ".join([str(s) for s in grammar.Nonterminals[nonterm]])) - debuglog.info("") - - if check_recursion: - unreachable = grammar.find_unreachable() - for u in unreachable: - errorlog.warning("Symbol '%s' is unreachable",u) - - infinite = grammar.infinite_cycles() - for inf in infinite: - errorlog.error("Infinite recursion detected for symbol '%s'", inf) - errors = 1 - - unused_prec = grammar.unused_precedence() - for term, assoc in unused_prec: - errorlog.error("Precedence rule '%s' defined for unknown symbol '%s'", assoc, term) - errors = 1 - - if errors: - raise YaccError("Unable to build parser") - - # Run the LRGeneratedTable on the grammar - if debug: - errorlog.debug("Generating %s tables", method) - - lr = LRGeneratedTable(grammar,method,debuglog) - - if debug: - num_sr = len(lr.sr_conflicts) - - # Report shift/reduce and reduce/reduce conflicts - if num_sr == 1: - errorlog.warning("1 shift/reduce conflict") - elif num_sr > 1: - errorlog.warning("%d shift/reduce conflicts", num_sr) - - num_rr = len(lr.rr_conflicts) - if num_rr == 1: - errorlog.warning("1 reduce/reduce conflict") - elif num_rr > 1: - errorlog.warning("%d reduce/reduce conflicts", num_rr) - - # Write out conflicts to the output file - if debug and (lr.sr_conflicts or lr.rr_conflicts): - debuglog.warning("") - debuglog.warning("Conflicts:") - debuglog.warning("") - - for state, tok, resolution in lr.sr_conflicts: - debuglog.warning("shift/reduce conflict for %s in state %d resolved as %s", tok, state, resolution) - - already_reported = {} - for state, rule, rejected in lr.rr_conflicts: - if (state,id(rule),id(rejected)) in already_reported: - continue - debuglog.warning("reduce/reduce conflict in state %d resolved using rule (%s)", state, rule) - debuglog.warning("rejected rule (%s) in state %d", rejected,state) - errorlog.warning("reduce/reduce conflict in state %d resolved using rule (%s)", state, rule) - errorlog.warning("rejected rule (%s) in state %d", rejected, state) - already_reported[state,id(rule),id(rejected)] = 1 - - warned_never = [] - for state, rule, rejected in lr.rr_conflicts: - if not rejected.reduced and (rejected not in warned_never): - debuglog.warning("Rule (%s) is never reduced", rejected) - errorlog.warning("Rule (%s) is never reduced", rejected) - warned_never.append(rejected) - - # Write the table file if requested - if write_tables: - lr.write_table(tabmodule,outputdir,signature) - - # Write a pickled version of the tables - if picklefile: - lr.pickle_table(picklefile,signature) - - # Build the parser - lr.bind_callables(pinfo.pdict) - parser = LRParser(lr,pinfo.error_func) - - parse = parser.parse - return parser diff --git a/plugins_available/pycparser/pycparser/plyparser.py b/plugins_available/pycparser/pycparser/plyparser.py deleted file mode 100644 index 8e9e573..0000000 --- a/plugins_available/pycparser/pycparser/plyparser.py +++ /dev/null @@ -1,67 +0,0 @@ -#----------------------------------------------------------------- -# plyparser.py -# -# PLYParser class and other utilites for simplifying programming -# parsers with PLY -# -# Copyright (C) 2008-2009, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - - -class Coord(object): - """ Coordinates of a syntactic element. Consists of: - - File name - - Line number - - (optional) column number, for the Lexer - """ - def __init__(self, file, line, column=None): - self.file = file - self.line = line - self.column = column - - def __str__(self): - str = "%s:%s" % (self.file, self.line) - if self.column: str += ":%s" % self.column - return str - - -class ParseError(Exception): pass - - -class PLYParser(object): - def _create_opt_rule(self, rulename): - """ Given a rule name, creates an optional ply.yacc rule - for it. The name of the optional rule is - _opt - """ - optname = rulename + '_opt' - - def optrule(self, p): - p[0] = p[1] - - optrule.__doc__ = '%s : empty\n| %s' % (optname, rulename) - optrule.__name__ = 'p_%s' % optname - setattr(self.__class__, optrule.__name__, optrule) - - def _coord(self, lineno, column=None): - return Coord( - file=self.clex.filename, - line=lineno, - column=column) - - def _parse_error(self, msg, coord): - raise ParseError("%s: %s" % (coord, msg)) - - -if __name__ == '__main__': - pp = PLYParser() - pp._create_opt_rule('java') - - ar = [4, 6] - pp.p_java_opt(ar) - - print ar - print pp.p_java_opt.__doc__ - - print dir(pp) diff --git a/plugins_available/pycparser/yacctab.py b/plugins_available/pycparser/yacctab.py deleted file mode 100644 index 544f84c..0000000 --- a/plugins_available/pycparser/yacctab.py +++ /dev/null @@ -1,250 +0,0 @@ - -# yacctab.py -# This file is automatically generated. Do not edit. -_tabversion = '3.2' - -_lr_method = 'LALR' - -_lr_signature = "\n\x9d\xda\xf6\xeb\xf5\x97'\n\xff\xf7b(G7V" - -_lr_action_items = {'VOID':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[6,6,-51,-61,-60,-49,-46,-47,-27,-23,6,-45,-57,-53,-58,-44,6,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,6,-56,-54,-59,-62,6,-70,6,-69,-95,-24,6,-85,-84,6,-38,-39,6,-97,6,6,6,-76,6,6,6,6,-29,-40,6,-77,-71,6,6,-98,-100,-99,6,6,-86,-30,6,-73,-78,-72,6,6,-88,-87,-127,-128,-129,]),'LBRACKET':([1,2,3,5,6,8,9,12,14,15,16,17,19,21,22,23,25,28,31,33,34,36,37,38,39,40,42,43,44,46,48,49,50,54,56,57,58,59,60,67,73,76,78,83,84,85,86,87,90,95,97,101,102,106,107,111,116,125,126,136,137,138,139,140,149,153,160,183,184,185,186,191,192,197,229,231,236,238,239,242,258,259,260,288,292,295,320,321,327,328,329,347,348,],[-221,-51,-61,-60,-49,-46,-47,-221,-45,-57,-53,-58,-44,-48,-149,52,-221,-96,-50,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,52,-85,-84,-22,-101,-103,-21,-41,-97,-221,-221,-219,-210,-220,-218,-208,151,-217,-199,-214,-209,-216,-215,-207,189,-104,-102,-71,-17,-68,-18,-67,-205,-206,189,-98,-100,-99,189,286,189,-86,-214,-73,-72,-204,-203,-202,189,189,-211,286,-88,-87,-200,-201,-126,-122,-124,-123,-125,]),'WCHAR_CONST':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[85,-38,-39,-198,85,-196,-195,85,85,-194,85,85,-193,-197,85,85,-40,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-32,-35,-31,85,85,-33,85,85,-130,-36,85,-34,85,-155,-158,-156,-152,-153,-157,-159,85,-161,-162,-154,-160,85,85,85,-127,-146,85,-128,-145,85,-143,-131,85,85,85,-142,85,85,85,85,85,-141,-129,-144,-134,85,-132,85,85,-133,85,85,85,-138,-137,-135,85,-139,85,-136,85,-140,]),'FLOAT_CONST':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[86,-38,-39,-198,86,-196,-195,86,86,-194,86,86,-193,-197,86,86,-40,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-32,-35,-31,86,86,-33,86,86,-130,-36,86,-34,86,-155,-158,-156,-152,-153,-157,-159,86,-161,-162,-154,-160,86,86,86,-127,-146,86,-128,-145,86,-143,-131,86,86,86,-142,86,86,86,86,86,-141,-129,-144,-134,86,-132,86,86,-133,86,86,86,-138,-137,-135,86,-139,86,-136,86,-140,]),'MINUS':([52,66,70,81,82,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101,102,103,104,106,107,110,111,128,131,133,143,146,147,149,151,152,153,154,155,156,157,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,229,232,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,319,320,321,322,324,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[89,-38,-39,-198,-185,-219,-210,-220,-218,-208,89,-196,-187,-195,89,89,-217,-194,-199,89,-166,89,-214,-209,-193,167,-216,-215,-197,-207,89,89,-40,89,89,-191,-205,89,89,-206,-190,89,-188,-185,-189,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,-32,-35,-31,89,89,-33,89,89,-130,-36,89,-34,-214,89,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,89,-161,-162,-154,-160,89,-211,89,167,167,167,-171,167,167,167,-170,167,167,-168,-167,167,167,167,167,167,-169,89,-127,-146,89,-128,-145,89,-143,-131,89,89,89,-142,89,89,-192,-200,-201,89,-186,89,89,-141,-129,-144,-134,89,-132,89,89,-133,89,89,89,-138,-137,-135,89,-139,89,-136,89,-140,]),'RPAREN':([1,2,3,5,6,8,9,12,14,15,16,17,19,21,22,23,25,28,31,33,34,36,37,38,39,40,42,43,44,45,46,48,49,50,53,54,56,57,58,59,60,67,73,76,78,82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,112,113,114,115,116,117,118,119,125,126,136,137,138,139,140,147,149,152,153,154,156,157,158,159,160,161,162,163,183,184,185,186,187,188,190,191,192,193,197,218,231,236,237,238,239,241,242,243,257,258,259,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,281,282,283,284,287,288,289,290,291,292,295,302,319,320,321,323,324,325,327,328,329,331,339,341,344,345,346,347,348,360,362,365,],[-221,-51,-61,-60,-49,-46,-47,-221,-45,-57,-53,-58,-44,-48,-149,-94,-221,-96,-50,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,73,-70,-69,-42,-95,-221,-85,-84,-22,-101,-103,-21,-41,-97,-221,-221,-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,-164,-216,-215,-207,184,-11,185,-107,-221,-12,-105,-111,-104,-102,-71,-17,-68,-18,-67,-191,-205,242,-206,-190,-188,-185,256,-147,-221,-150,260,-189,-98,-100,-99,-221,-110,-2,-109,-121,-119,-1,-86,-10,-73,-72,319,-204,-203,-212,-202,321,-118,-221,-119,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-15,-16,327,328,-221,-120,-112,-106,-108,-88,-87,-9,-192,-200,-201,-151,-186,-148,-126,-122,-124,348,352,354,356,-213,-165,-123,-125,363,-221,367,]),'LONG':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[16,16,-51,-61,-60,-49,-46,-47,-27,-23,16,-45,-57,-53,-58,-44,16,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,16,-56,-54,-59,-62,16,-70,16,-69,-95,-24,16,-85,-84,16,-38,-39,16,-97,16,16,16,-76,16,16,16,16,-29,-40,16,-77,-71,16,16,-98,-100,-99,16,16,-86,-30,16,-73,-78,-72,16,16,-88,-87,-127,-128,-129,]),'PLUS':([52,66,70,81,82,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101,102,103,104,106,107,110,111,128,131,133,143,146,147,149,151,152,153,154,155,156,157,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,229,232,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,319,320,321,322,324,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[91,-38,-39,-198,-185,-219,-210,-220,-218,-208,91,-196,-187,-195,91,91,-217,-194,-199,91,-166,91,-214,-209,-193,171,-216,-215,-197,-207,91,91,-40,91,91,-191,-205,91,91,-206,-190,91,-188,-185,-189,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,-32,-35,-31,91,91,-33,91,91,-130,-36,91,-34,-214,91,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,91,-161,-162,-154,-160,91,-211,91,171,171,171,-171,171,171,171,-170,171,171,-168,-167,171,171,171,171,171,-169,91,-127,-146,91,-128,-145,91,-143,-131,91,91,91,-142,91,91,-192,-200,-201,91,-186,91,91,-141,-129,-144,-134,91,-132,91,91,-133,91,91,91,-138,-137,-135,91,-139,91,-136,91,-140,]),'ELLIPSIS':([195,],[290,]),'GT':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,172,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,172,-173,-171,-175,172,-174,-170,-177,172,-168,-167,-176,172,172,172,172,-169,-192,-200,-201,-186,]),'RBRACE':([66,70,75,77,82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,109,111,121,122,123,131,133,134,135,145,147,149,153,154,156,157,161,163,196,198,200,203,206,207,209,211,212,214,217,223,224,226,228,235,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,293,294,296,297,299,300,301,303,304,307,308,313,319,320,321,323,324,332,333,334,335,336,338,343,346,349,350,353,358,359,361,363,366,368,],[-38,-39,136,-76,-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,-164,-216,-215,-163,-207,-89,197,-92,-221,-40,231,-77,236,-191,-205,-206,-190,-188,-185,-150,-189,292,-90,295,-113,-32,-35,299,-31,303,-33,-20,-130,-36,-19,-34,-78,-204,-203,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-91,-93,-116,333,-127,-146,335,-128,-145,-143,-131,-142,-192,-200,-201,-151,-186,350,-114,-141,-129,-144,-134,-132,-165,-117,-115,-133,-138,-137,-135,-139,-136,-140,]),'ENUM':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[24,24,-51,-61,-60,-49,-46,-47,-27,-23,24,-45,-57,-53,-58,-44,24,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,24,-56,-54,-59,-62,24,-70,24,-69,-95,-24,24,-85,-84,24,-38,-39,24,-97,24,24,24,-76,24,24,24,24,-29,-40,24,-77,-71,24,24,-98,-100,-99,24,24,-86,-30,24,-73,-78,-72,24,24,-88,-87,-127,-128,-129,]),'PERIOD':([83,84,85,86,87,90,95,97,101,102,106,107,111,149,153,229,238,239,242,260,320,321,],[-219,-210,-220,-218,-208,150,-217,-199,-214,-209,-216,-215,-207,-205,-206,-214,-204,-203,-202,-211,-200,-201,]),'GE':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,176,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,176,-173,-171,-175,176,-174,-170,-177,176,-168,-167,-176,176,176,176,176,-169,-192,-200,-201,-186,]),'INT_CONST_DEC':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[107,-38,-39,-198,107,-196,-195,107,107,-194,107,107,-193,-197,107,107,-40,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,-32,-35,-31,107,107,-33,107,107,-130,-36,107,-34,107,-155,-158,-156,-152,-153,-157,-159,107,-161,-162,-154,-160,107,107,107,-127,-146,107,-128,-145,107,-143,-131,107,107,107,-142,107,107,107,107,107,-141,-129,-144,-134,107,-132,107,107,-133,107,107,107,-138,-137,-135,107,-139,107,-136,107,-140,]),'ARROW':([83,84,85,86,87,90,95,97,101,102,106,107,111,149,153,229,238,239,242,260,320,321,],[-219,-210,-220,-218,-208,148,-217,-199,-214,-209,-216,-215,-207,-205,-206,-214,-204,-203,-202,-211,-200,-201,]),'DOUBLE':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[34,34,-51,-61,-60,-49,-46,-47,-27,-23,34,-45,-57,-53,-58,-44,34,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,34,-56,-54,-59,-62,34,-70,34,-69,-95,-24,34,-85,-84,34,-38,-39,34,-97,34,34,34,-76,34,34,34,34,-29,-40,34,-77,-71,34,34,-98,-100,-99,34,34,-86,-30,34,-73,-78,-72,34,34,-88,-87,-127,-128,-129,]),'MINUSEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,245,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'INT_CONST_OCT':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[106,-38,-39,-198,106,-196,-195,106,106,-194,106,106,-193,-197,106,106,-40,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,-32,-35,-31,106,106,-33,106,106,-130,-36,106,-34,106,-155,-158,-156,-152,-153,-157,-159,106,-161,-162,-154,-160,106,106,106,-127,-146,106,-128,-145,106,-143,-131,106,106,106,-142,106,106,106,106,106,-141,-129,-144,-134,106,-132,106,106,-133,106,106,106,-138,-137,-135,106,-139,106,-136,106,-140,]),'TIMESEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,254,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'OR':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,181,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,181,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,181,-178,-180,-181,-169,-192,-200,-201,-186,]),'SHORT':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[2,2,-51,-61,-60,-49,-46,-47,-27,-23,2,-45,-57,-53,-58,-44,2,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,2,-56,-54,-59,-62,2,-70,2,-69,-95,-24,2,-85,-84,2,-38,-39,2,-97,2,2,2,-76,2,2,2,2,-29,-40,2,-77,-71,2,2,-98,-100,-99,2,2,-86,-30,2,-73,-78,-72,2,2,-88,-87,-127,-128,-129,]),'RETURN':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,213,-40,-32,-35,-31,213,-33,213,-130,-36,213,-34,-127,-146,213,-128,-145,-143,-131,213,-142,213,-141,-129,-144,-134,213,-132,213,-133,213,213,-138,-137,-135,-139,213,-136,213,-140,]),'RSHIFTEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,255,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'STATIC':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,48,50,51,53,54,56,64,66,70,72,73,131,132,133,136,183,184,185,186,195,197,205,212,231,236,258,287,292,295,299,303,335,],[8,8,-51,-61,-60,-49,-46,-47,-27,-23,8,-45,-57,-53,-58,-44,8,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,8,-56,-54,-59,-62,8,-70,-69,-95,-24,8,-85,-84,8,-38,-39,8,-97,8,-29,-40,-71,-98,-100,-99,8,8,-86,-30,8,-73,-72,8,8,-88,-87,-127,-128,-129,]),'SIZEOF':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[88,-38,-39,-198,88,-196,-195,88,88,-194,88,88,-193,-197,88,88,-40,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-32,-35,-31,88,88,-33,88,88,-130,-36,88,-34,88,-155,-158,-156,-152,-153,-157,-159,88,-161,-162,-154,-160,88,88,88,-127,-146,88,-128,-145,88,-143,-131,88,88,88,-142,88,88,88,88,88,-141,-129,-144,-134,88,-132,88,88,-133,88,88,88,-138,-137,-135,88,-139,88,-136,88,-140,]),'UNSIGNED':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[15,15,-51,-61,-60,-49,-46,-47,-27,-23,15,-45,-57,-53,-58,-44,15,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,15,-56,-54,-59,-62,15,-70,15,-69,-95,-24,15,-85,-84,15,-38,-39,15,-97,15,15,15,-76,15,15,15,15,-29,-40,15,-77,-71,15,15,-98,-100,-99,15,15,-86,-30,15,-73,-78,-72,15,15,-88,-87,-127,-128,-129,]),'UNION':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[18,18,-51,-61,-60,-49,-46,-47,-27,-23,18,-45,-57,-53,-58,-44,18,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,18,-56,-54,-59,-62,18,-70,18,-69,-95,-24,18,-85,-84,18,-38,-39,18,-97,18,18,18,-76,18,18,18,18,-29,-40,18,-77,-71,18,18,-98,-100,-99,18,18,-86,-30,18,-73,-78,-72,18,18,-88,-87,-127,-128,-129,]),'COLON':([2,3,5,6,15,16,17,22,23,28,31,33,34,37,38,39,40,46,48,50,54,56,73,76,78,79,82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,109,111,136,137,138,139,140,142,147,149,153,154,156,157,159,161,163,183,184,185,197,219,229,231,234,236,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,292,295,311,319,320,321,323,324,325,346,],[-51,-61,-60,-49,-57,-53,-58,-149,-94,-96,-50,-52,-55,-56,-54,-59,-62,-70,-69,-95,-85,-84,-97,-221,-221,143,-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,-164,-216,-215,-163,-207,-71,-17,-68,-18,-67,232,-191,-205,-206,-190,-188,-185,-147,-150,-189,-98,-100,-99,-86,309,315,-73,143,-72,-204,-203,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,326,-181,-169,-88,-87,340,-192,-200,-201,-151,-186,-148,-165,]),'$end':([10,11,20,27,30,32,51,66,132,205,299,303,335,],[-27,-23,0,-26,-25,-28,-24,-38,-29,-30,-127,-128,-129,]),'WSTRING_LITERAL':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[84,-38,-39,-198,84,-196,-195,84,84,-194,84,84,-193,-197,84,84,-40,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-32,-35,-31,84,84,-33,84,84,-130,-36,84,-34,84,-155,-158,-156,-152,-153,-157,-159,84,-161,-162,-154,-160,84,84,84,-127,-146,84,-128,-145,84,-143,-131,84,84,84,-142,84,84,84,84,84,-141,-129,-144,-134,84,-132,84,84,-133,84,84,84,-138,-137,-135,84,-139,84,-136,84,-140,]),'DIVIDE':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,174,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,174,174,174,174,174,174,174,174,174,174,-168,-167,174,174,174,174,174,-169,-192,-200,-201,-186,]),'FOR':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,215,-40,-32,-35,-31,215,-33,215,-130,-36,215,-34,-127,-146,215,-128,-145,-143,-131,215,-142,215,-141,-129,-144,-134,215,-132,215,-133,215,215,-138,-137,-135,-139,215,-136,215,-140,]),'PLUSPLUS':([52,66,70,81,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,100,101,102,103,106,107,110,111,128,131,133,143,146,149,151,152,153,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,229,232,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,260,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,320,321,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[94,-38,-39,-198,-219,-210,-220,-218,-208,94,-196,149,-195,94,94,-217,-194,-199,94,94,-214,-209,-193,-216,-215,-197,-207,94,94,-40,94,94,-205,94,94,-206,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,-32,-35,-31,94,94,-33,94,94,-130,-36,94,-34,-214,94,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,94,-161,-162,-154,-160,94,-211,94,94,-127,-146,94,-128,-145,94,-143,-131,94,94,94,-142,94,94,-200,-201,94,94,94,-141,-129,-144,-134,94,-132,94,94,-133,94,94,94,-138,-137,-135,94,-139,94,-136,94,-140,]),'EQUALS':([23,28,50,64,73,82,83,84,85,86,87,90,95,97,101,102,106,107,111,123,130,147,149,153,154,156,157,163,183,184,185,229,238,239,242,260,319,320,321,324,],[-94,-96,-95,128,-97,-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,199,128,-191,-205,-206,-190,-188,247,-189,-98,-100,-99,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'ELSE':([206,207,211,214,224,228,299,300,303,304,307,313,334,335,336,338,343,353,358,359,361,363,366,368,],[-32,-35,-31,-33,-36,-34,-127,-146,-128,-145,-143,-142,-141,-129,-144,-134,-132,-133,-138,-137,364,-139,-136,-140,]),'EQ':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,178,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,178,-173,-171,-175,-179,-174,-170,-177,178,-168,-167,-176,178,-178,178,178,-169,-192,-200,-201,-186,]),'AND':([52,66,70,81,82,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101,102,103,104,106,107,110,111,128,131,133,143,146,147,149,151,152,153,154,155,156,157,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,229,232,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,319,320,321,322,324,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[103,-38,-39,-198,-185,-219,-210,-220,-218,-208,103,-196,-187,-195,103,103,-217,-194,-199,103,-166,103,-214,-209,-193,179,-216,-215,-197,-207,103,103,-40,103,103,-191,-205,103,103,-206,-190,103,-188,-185,-189,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,-32,-35,-31,103,103,-33,103,103,-130,-36,103,-34,-214,103,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,103,-161,-162,-154,-160,103,-211,103,-172,179,-173,-171,-175,-179,-174,-170,-177,179,-168,-167,-176,179,-178,-180,179,-169,103,-127,-146,103,-128,-145,103,-143,-131,103,103,103,-142,103,103,-192,-200,-201,103,-186,103,103,-141,-129,-144,-134,103,-132,103,103,-133,103,103,103,-138,-137,-135,103,-139,103,-136,103,-140,]),'TYPEID':([0,1,2,3,5,6,7,8,9,10,11,12,14,15,16,17,18,19,20,21,22,23,24,27,28,29,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[22,22,-51,-61,-60,-49,46,-46,-47,-27,-23,22,-45,-57,-53,-58,-75,-44,22,-48,-149,-94,54,-26,-96,-74,-25,-50,-28,-52,-55,22,-56,-54,-59,-62,22,-70,22,-69,-95,-24,22,-85,-84,22,-38,-39,22,-97,22,22,22,-76,22,22,22,22,-29,-40,22,-77,-71,22,22,-98,-100,-99,22,22,-86,-30,22,-73,-78,-72,22,22,-88,-87,-127,-128,-129,]),'LBRACE':([7,18,23,24,28,29,41,46,48,50,54,56,64,66,68,70,71,72,73,128,129,131,133,183,184,185,204,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,332,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[47,-75,-94,55,-96,-74,-221,74,80,-95,120,124,-221,-38,-5,-39,131,-6,-97,204,131,131,-40,-98,-100,-99,204,-32,-35,-31,131,-33,131,-130,-36,131,-34,-127,-146,131,-128,-145,-143,-131,131,-142,131,204,-141,-129,-144,-134,131,-132,131,-133,131,131,-138,-137,-135,-139,131,-136,131,-140,]),'PPHASH':([0,10,11,20,27,30,32,51,66,132,205,299,303,335,],[32,-27,-23,32,-26,-25,-28,-24,-38,-29,-30,-127,-128,-129,]),'INT':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[33,33,-51,-61,-60,-49,-46,-47,-27,-23,33,-45,-57,-53,-58,-44,33,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,33,-56,-54,-59,-62,33,-70,33,-69,-95,-24,33,-85,-84,33,-38,-39,33,-97,33,33,33,-76,33,33,33,33,-29,-40,33,-77,-71,33,33,-98,-100,-99,33,33,-86,-30,33,-73,-78,-72,33,33,-88,-87,-127,-128,-129,]),'SIGNED':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[37,37,-51,-61,-60,-49,-46,-47,-27,-23,37,-45,-57,-53,-58,-44,37,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,37,-56,-54,-59,-62,37,-70,37,-69,-95,-24,37,-85,-84,37,-38,-39,37,-97,37,37,37,-76,37,37,37,37,-29,-40,37,-77,-71,37,37,-98,-100,-99,37,37,-86,-30,37,-73,-78,-72,37,37,-88,-87,-127,-128,-129,]),'CONTINUE':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,216,-40,-32,-35,-31,216,-33,216,-130,-36,216,-34,-127,-146,216,-128,-145,-143,-131,216,-142,216,-141,-129,-144,-134,216,-132,216,-133,216,216,-138,-137,-135,-139,216,-136,216,-140,]),'NOT':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[110,-38,-39,-198,110,-196,-195,110,110,-194,110,110,-193,-197,110,110,-40,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,-32,-35,-31,110,110,-33,110,110,-130,-36,110,-34,110,-155,-158,-156,-152,-153,-157,-159,110,-161,-162,-154,-160,110,110,110,-127,-146,110,-128,-145,110,-143,-131,110,110,110,-142,110,110,110,110,110,-141,-129,-144,-134,110,-132,110,110,-133,110,110,110,-138,-137,-135,110,-139,110,-136,110,-140,]),'OREQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,253,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'MOD':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,182,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,182,182,182,182,182,182,182,182,182,182,-168,-167,182,182,182,182,182,-169,-192,-200,-201,-186,]),'RSHIFT':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,164,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,164,-173,-171,164,164,164,-170,164,164,-168,-167,164,164,164,164,164,-169,-192,-200,-201,-186,]),'DEFAULT':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,219,-40,-32,-35,-31,219,-33,219,-130,-36,219,-34,-127,-146,219,-128,-145,-143,-131,219,-142,219,-141,-129,-144,-134,219,-132,219,-133,219,219,-138,-137,-135,-139,219,-136,219,-140,]),'CHAR':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[31,31,-51,-61,-60,-49,-46,-47,-27,-23,31,-45,-57,-53,-58,-44,31,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,31,-56,-54,-59,-62,31,-70,31,-69,-95,-24,31,-85,-84,31,-38,-39,31,-97,31,31,31,-76,31,31,31,31,-29,-40,31,-77,-71,31,31,-98,-100,-99,31,31,-86,-30,31,-73,-78,-72,31,31,-88,-87,-127,-128,-129,]),'WHILE':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,314,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,220,-40,-32,-35,-31,220,-33,220,-130,-36,220,-34,-127,-146,220,-128,-145,-143,-131,220,-142,342,220,-141,-129,-144,-134,220,-132,220,-133,220,220,-138,-137,-135,-139,220,-136,220,-140,]),'DIVEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,244,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'EXTERN':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,48,50,51,53,54,56,64,66,70,72,73,131,132,133,136,183,184,185,186,195,197,205,212,231,236,258,287,292,295,299,303,335,],[9,9,-51,-61,-60,-49,-46,-47,-27,-23,9,-45,-57,-53,-58,-44,9,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,9,-56,-54,-59,-62,9,-70,-69,-95,-24,9,-85,-84,9,-38,-39,9,-97,9,-29,-40,-71,-98,-100,-99,9,9,-86,-30,9,-73,-72,9,9,-88,-87,-127,-128,-129,]),'CASE':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,221,-40,-32,-35,-31,221,-33,221,-130,-36,221,-34,-127,-146,221,-128,-145,-143,-131,221,-142,221,-141,-129,-144,-134,221,-132,221,-133,221,221,-138,-137,-135,-139,221,-136,221,-140,]),'LAND':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,177,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,177,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-192,-200,-201,-186,]),'REGISTER':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,48,50,51,53,54,56,64,66,70,72,73,131,132,133,136,183,184,185,186,195,197,205,212,231,236,258,287,292,295,299,303,335,],[14,14,-51,-61,-60,-49,-46,-47,-27,-23,14,-45,-57,-53,-58,-44,14,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,14,-56,-54,-59,-62,14,-70,-69,-95,-24,14,-85,-84,14,-38,-39,14,-97,14,-29,-40,-71,-98,-100,-99,14,14,-86,-30,14,-73,-72,14,14,-88,-87,-127,-128,-129,]),'MODEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,246,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'NE':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,169,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,169,-173,-171,-175,-179,-174,-170,-177,169,-168,-167,-176,169,-178,169,169,-169,-192,-200,-201,-186,]),'SWITCH':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,222,-40,-32,-35,-31,222,-33,222,-130,-36,222,-34,-127,-146,222,-128,-145,-143,-131,222,-142,222,-141,-129,-144,-134,222,-132,222,-133,222,222,-138,-137,-135,-139,222,-136,222,-140,]),'INT_CONST_HEX':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[95,-38,-39,-198,95,-196,-195,95,95,-194,95,95,-193,-197,95,95,-40,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,-32,-35,-31,95,95,-33,95,95,-130,-36,95,-34,95,-155,-158,-156,-152,-153,-157,-159,95,-161,-162,-154,-160,95,95,95,-127,-146,95,-128,-145,95,-143,-131,95,95,95,-142,95,95,95,95,95,-141,-129,-144,-134,95,-132,95,95,-133,95,95,95,-138,-137,-135,95,-139,95,-136,95,-140,]),'PLUSEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,249,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'STRUCT':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[29,29,-51,-61,-60,-49,-46,-47,-27,-23,29,-45,-57,-53,-58,-44,29,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,29,-56,-54,-59,-62,29,-70,29,-69,-95,-24,29,-85,-84,29,-38,-39,29,-97,29,29,29,-76,29,29,29,29,-29,-40,29,-77,-71,29,29,-98,-100,-99,29,29,-86,-30,29,-73,-78,-72,29,29,-88,-87,-127,-128,-129,]),'CONDOP':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,180,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-192,-200,-201,-186,]),'BREAK':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,225,-40,-32,-35,-31,225,-33,225,-130,-36,225,-34,-127,-146,225,-128,-145,-143,-131,225,-142,225,-141,-129,-144,-134,225,-132,225,-133,225,225,-138,-137,-135,-139,225,-136,225,-140,]),'VOLATILE':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,25,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,57,59,64,66,70,72,73,74,75,76,77,78,80,98,125,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[40,40,-51,-61,-60,-49,-46,-47,-27,-23,40,-45,-57,-53,-58,-44,40,-48,-149,-94,40,-26,-96,-25,-50,-28,-52,-55,40,-56,-54,-59,-62,40,-70,40,-69,-95,-24,40,-85,-84,40,-103,40,-38,-39,40,-97,40,40,40,-76,40,40,40,-104,40,-29,-40,40,-77,-71,40,40,-98,-100,-99,40,40,-86,-30,40,-73,-78,-72,40,40,-88,-87,-127,-128,-129,]),'ANDEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,252,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'DO':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,227,-40,-32,-35,-31,227,-33,227,-130,-36,227,-34,-127,-146,227,-128,-145,-143,-131,227,-142,227,-141,-129,-144,-134,227,-132,227,-133,227,227,-138,-137,-135,-139,227,-136,227,-140,]),'LNOT':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[81,-38,-39,-198,81,-196,-195,81,81,-194,81,81,-193,-197,81,81,-40,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,-32,-35,-31,81,81,-33,81,81,-130,-36,81,-34,81,-155,-158,-156,-152,-153,-157,-159,81,-161,-162,-154,-160,81,81,81,-127,-146,81,-128,-145,81,-143,-131,81,81,81,-142,81,81,81,81,81,-141,-129,-144,-134,81,-132,81,81,-133,81,81,81,-138,-137,-135,81,-139,81,-136,81,-140,]),'CONST':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,25,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,57,59,64,66,70,72,73,74,75,76,77,78,80,98,125,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[3,3,-51,-61,-60,-49,-46,-47,-27,-23,3,-45,-57,-53,-58,-44,3,-48,-149,-94,3,-26,-96,-25,-50,-28,-52,-55,3,-56,-54,-59,-62,3,-70,3,-69,-95,-24,3,-85,-84,3,-103,3,-38,-39,3,-97,3,3,3,-76,3,3,3,-104,3,-29,-40,3,-77,-71,3,3,-98,-100,-99,3,3,-86,-30,3,-73,-78,-72,3,3,-88,-87,-127,-128,-129,]),'LOR':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,165,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-192,-200,-201,-186,]),'CHAR_CONST':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[83,-38,-39,-198,83,-196,-195,83,83,-194,83,83,-193,-197,83,83,-40,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-32,-35,-31,83,83,-33,83,83,-130,-36,83,-34,83,-155,-158,-156,-152,-153,-157,-159,83,-161,-162,-154,-160,83,83,83,-127,-146,83,-128,-145,83,-143,-131,83,83,83,-142,83,83,83,83,83,-141,-129,-144,-134,83,-132,83,83,-133,83,83,83,-138,-137,-135,83,-139,83,-136,83,-140,]),'LSHIFT':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,166,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,166,-173,-171,166,166,166,-170,166,166,-168,-167,166,166,166,166,166,-169,-192,-200,-201,-186,]),'GOTO':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,208,-40,-32,-35,-31,208,-33,208,-130,-36,208,-34,-127,-146,208,-128,-145,-143,-131,208,-142,208,-141,-129,-144,-134,208,-132,208,-133,208,208,-138,-137,-135,-139,208,-136,208,-140,]),'LE':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,168,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,168,-173,-171,-175,168,-174,-170,-177,168,-168,-167,-176,168,168,168,168,-169,-192,-200,-201,-186,]),'SEMI':([1,2,3,5,6,8,9,12,14,15,16,17,19,21,22,23,26,28,31,33,34,35,36,37,38,39,40,42,43,44,46,48,49,50,54,56,61,62,63,64,65,66,67,69,70,73,82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,109,111,130,131,133,136,141,142,144,147,149,153,154,156,157,159,161,163,183,184,185,197,201,202,203,206,207,210,211,212,213,214,216,217,218,223,224,225,226,227,228,229,231,233,236,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,292,295,298,299,300,301,302,303,304,305,306,307,308,309,313,315,317,318,319,320,321,323,324,325,333,334,335,336,337,338,340,343,346,350,351,352,353,354,356,357,358,359,361,363,364,366,367,368,],[-221,-51,-61,-60,-49,-46,-47,-221,-45,-57,-53,-58,-44,-48,-149,-94,-221,-96,-50,-52,-55,66,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,-95,-85,-84,-14,-37,-13,-65,-63,-38,-41,-221,-39,-97,-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,-164,-216,-215,-163,-207,-65,-221,-40,-71,-79,-81,235,-191,-205,-206,-190,-188,-185,-147,-150,-189,-98,-100,-99,-86,-64,-66,-113,-32,-35,300,-31,-221,304,-33,307,-221,-10,-130,-36,313,-9,-221,-34,-214,-73,-83,-72,-204,-203,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-88,-87,334,-127,-146,-221,-9,-128,-145,336,-221,-143,-131,-221,-142,-221,-82,-80,-192,-200,-201,-151,-186,-148,-114,-141,-129,-144,351,-134,-221,-132,-165,-115,-221,-221,-133,-221,-221,362,-138,-137,-135,-139,-221,-136,-221,-140,]),'LT':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,170,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,170,-173,-171,-175,170,-174,-170,-177,170,-168,-167,-176,170,170,170,170,-169,-192,-200,-201,-186,]),'COMMA':([1,2,3,5,6,8,9,12,14,15,16,17,19,21,22,23,25,28,31,33,34,36,37,38,39,40,42,43,44,46,48,49,50,54,56,57,58,59,60,61,64,65,67,73,82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,109,111,115,116,117,118,119,121,122,123,125,126,130,136,141,142,144,147,149,153,154,156,157,159,161,162,163,183,184,185,187,188,190,191,192,193,196,197,198,200,201,202,203,218,229,231,233,236,238,239,240,241,242,243,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,288,289,291,292,293,294,295,296,297,305,317,318,319,320,321,323,324,325,327,328,329,333,339,341,344,345,346,347,348,349,350,360,],[-221,-51,-61,-60,-49,-46,-47,-221,-45,-57,-53,-58,-44,-48,-149,-94,-221,-96,-50,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,-95,-85,-84,-22,-101,-103,-21,127,-65,-63,-41,-97,-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,-164,-216,-215,-163,-207,-107,-221,194,195,-111,-89,198,-92,-104,-102,-65,-71,-79,-81,234,-191,-205,-206,-190,-188,-185,-147,-150,261,-189,-98,-100,-99,-110,-2,-109,-121,-119,-1,198,-86,-90,198,-64,-66,-113,261,-214,-73,-83,-72,-204,-203,261,-212,-202,322,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,261,-181,-169,-120,-112,-108,-88,-91,-93,-87,-116,332,261,-82,-80,-192,-200,-201,-151,-186,-148,-126,-122,-124,-114,261,261,261,-213,-165,-123,-125,-117,-115,261,]),'TYPEDEF':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,48,50,51,53,54,56,64,66,70,72,73,131,132,133,136,183,184,185,186,195,197,205,212,231,236,258,287,292,295,299,303,335,],[21,21,-51,-61,-60,-49,-46,-47,-27,-23,21,-45,-57,-53,-58,-44,21,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,21,-56,-54,-59,-62,21,-70,-69,-95,-24,21,-85,-84,21,-38,-39,21,-97,21,-29,-40,-71,-98,-100,-99,21,21,-86,-30,21,-73,-72,21,21,-88,-87,-127,-128,-129,]),'XOR':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,173,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,173,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,173,-178,-180,173,-169,-192,-200,-201,-186,]),'AUTO':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,48,50,51,53,54,56,64,66,70,72,73,131,132,133,136,183,184,185,186,195,197,205,212,231,236,258,287,292,295,299,303,335,],[19,19,-51,-61,-60,-49,-46,-47,-27,-23,19,-45,-57,-53,-58,-44,19,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,19,-56,-54,-59,-62,19,-70,-69,-95,-24,19,-85,-84,19,-38,-39,19,-97,19,-29,-40,-71,-98,-100,-99,19,19,-86,-30,19,-73,-72,19,19,-88,-87,-127,-128,-129,]),'TIMES':([0,1,2,3,4,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,25,26,27,30,31,32,33,34,36,37,38,39,40,42,43,44,46,48,49,51,52,54,56,57,58,59,60,66,67,69,70,76,78,79,81,82,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101,102,103,104,106,107,110,111,116,125,127,128,131,132,133,136,137,138,139,140,143,146,147,149,151,152,153,154,155,156,157,160,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,186,189,197,199,204,205,206,207,211,212,213,214,217,221,223,224,227,228,229,231,232,234,236,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,258,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,286,292,295,299,300,301,303,304,306,307,308,309,310,312,313,315,316,319,320,321,322,324,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[25,-221,-51,-61,25,-60,-49,-46,-47,-27,-23,-221,-45,-57,-53,-58,-44,25,-48,-149,-221,25,-26,-25,-50,-28,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,-24,96,-85,-84,-22,25,-103,-21,-38,-41,25,-39,-221,-221,25,-198,-185,-219,-210,-220,-218,-208,96,-196,-187,-195,96,96,-217,-194,-199,96,-166,96,-214,-209,-193,175,-216,-215,-197,-207,25,-104,25,96,96,-29,-40,-71,-17,-68,-18,-67,96,96,-191,-205,96,96,-206,-190,96,-188,-185,25,-189,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,25,96,-86,96,96,-30,-32,-35,-31,96,96,-33,96,96,-130,-36,96,-34,-214,-73,96,25,-72,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,96,-161,-162,-154,-160,96,25,-211,96,175,175,175,175,175,175,175,175,175,175,-168,-167,175,175,175,175,175,-169,96,-88,-87,-127,-146,96,-128,-145,96,-143,-131,96,96,96,-142,96,96,-192,-200,-201,96,-186,96,96,-141,-129,-144,-134,96,-132,96,96,-133,96,96,96,-138,-137,-135,96,-139,96,-136,96,-140,]),'LPAREN':([0,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,19,20,21,22,23,25,26,27,28,30,31,32,33,34,36,37,38,39,40,42,43,44,46,48,49,50,51,52,54,56,57,58,59,60,66,67,69,70,73,76,78,79,81,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,100,101,102,103,106,107,110,111,116,125,126,127,128,131,132,133,136,137,138,139,140,143,146,149,151,152,153,155,160,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,189,191,192,197,199,204,205,206,207,211,212,213,214,215,217,220,221,222,223,224,227,228,229,230,231,232,234,236,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,258,259,260,261,286,288,292,295,299,300,301,303,304,306,307,308,309,310,312,313,315,316,320,321,322,326,327,328,329,332,334,335,336,338,340,342,343,347,348,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[4,-221,-51,-61,4,-60,-49,-46,-47,-27,-23,-221,4,-45,-57,-53,-58,-44,4,-48,-149,53,-221,4,-26,-96,-25,-50,-28,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,53,-24,98,-85,-84,-22,-101,-103,-21,-38,-41,4,-39,-97,-221,-221,4,-198,-219,-210,-220,-218,-208,146,-196,152,-195,98,155,-217,-194,-199,98,155,-214,-209,-193,-216,-215,-197,-207,186,-104,-102,4,98,98,-29,-40,-71,-17,-68,-18,-67,98,98,-205,98,98,-206,98,258,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,-98,-100,-99,186,98,287,186,-86,98,98,-30,-32,-35,-31,98,98,-33,306,98,310,98,312,-130,-36,98,-34,-214,316,-73,98,4,-72,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,98,-161,-162,-154,-160,98,258,258,-211,98,98,287,-88,-87,-127,-146,98,-128,-145,98,-143,-131,98,98,98,-142,98,98,-200,-201,98,98,-126,-122,-124,98,-141,-129,-144,-134,98,355,-132,-123,-125,98,98,-133,98,98,98,-138,-137,-135,98,-139,98,-136,98,-140,]),'MINUSMINUS':([52,66,70,81,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,100,101,102,103,106,107,110,111,128,131,133,143,146,149,151,152,153,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,229,232,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,260,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,320,321,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[100,-38,-39,-198,-219,-210,-220,-218,-208,100,-196,153,-195,100,100,-217,-194,-199,100,100,-214,-209,-193,-216,-215,-197,-207,100,100,-40,100,100,-205,100,100,-206,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,-32,-35,-31,100,100,-33,100,100,-130,-36,100,-34,-214,100,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,100,-161,-162,-154,-160,100,-211,100,100,-127,-146,100,-128,-145,100,-143,-131,100,100,100,-142,100,100,-200,-201,100,100,100,-141,-129,-144,-134,100,-132,100,100,-133,100,100,100,-138,-137,-135,100,-139,100,-136,100,-140,]),'ID':([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,29,30,31,32,33,34,36,37,38,39,40,42,43,44,46,48,49,51,52,53,54,55,56,57,58,59,60,66,67,69,70,76,78,79,81,88,89,91,92,94,96,98,100,103,110,116,120,124,125,126,127,128,131,132,133,136,137,138,139,140,143,146,148,150,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,186,189,192,194,197,198,199,204,205,206,207,208,211,212,213,214,217,221,223,224,227,228,231,232,234,236,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,292,295,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[28,-221,-51,-61,28,-60,-49,48,-46,-47,-27,-23,-221,28,-45,-57,-53,-58,-75,-44,28,-48,-149,56,-221,28,-26,-74,-25,-50,-28,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,-24,101,101,-85,123,-84,-22,-101,-103,-21,-38,-41,28,-39,-221,-221,28,-198,101,-196,-195,101,101,-194,101,101,-193,-197,28,123,123,-104,-102,28,101,229,-29,-40,-71,-17,-68,-18,-67,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,28,101,28,101,-86,123,101,101,-30,-32,-35,298,-31,229,101,-33,229,101,-130,-36,229,-34,-73,101,28,-72,-155,-158,-156,-152,-153,-157,-159,101,-161,-162,-154,-160,101,101,101,-88,-87,-127,-146,229,-128,-145,101,-143,-131,229,101,101,-142,229,101,101,101,101,-141,-129,-144,-134,229,-132,101,229,-133,229,101,229,-138,-137,-135,101,-139,229,-136,229,-140,]),'IF':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,230,-40,-32,-35,-31,230,-33,230,-130,-36,230,-34,-127,-146,230,-128,-145,-143,-131,230,-142,230,-141,-129,-144,-134,230,-132,230,-133,230,230,-138,-137,-135,-139,230,-136,230,-140,]),'STRING_LITERAL':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[102,-38,-39,-198,102,-196,-195,102,102,-194,102,102,-193,-197,102,102,-40,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-32,-35,-31,102,102,-33,102,102,-130,-36,102,-34,102,-155,-158,-156,-152,-153,-157,-159,102,-161,-162,-154,-160,102,102,102,-127,-146,102,-128,-145,102,-143,-131,102,102,102,-142,102,102,102,102,102,-141,-129,-144,-134,102,-132,102,102,-133,102,102,102,-138,-137,-135,102,-139,102,-136,102,-140,]),'FLOAT':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[38,38,-51,-61,-60,-49,-46,-47,-27,-23,38,-45,-57,-53,-58,-44,38,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,38,-56,-54,-59,-62,38,-70,38,-69,-95,-24,38,-85,-84,38,-38,-39,38,-97,38,38,38,-76,38,38,38,38,-29,-40,38,-77,-71,38,38,-98,-100,-99,38,38,-86,-30,38,-73,-78,-72,38,38,-88,-87,-127,-128,-129,]),'XOREQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,248,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'LSHIFTEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,250,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'RBRACKET':([52,82,83,84,85,86,87,90,93,95,97,99,101,102,104,105,106,107,108,109,111,147,149,153,154,156,157,159,161,163,189,238,239,240,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,285,286,319,320,321,323,324,325,330,346,],[-221,-185,-219,-210,-220,-218,-208,-187,-3,-217,-199,-166,-214,-209,-164,183,-216,-215,-4,-163,-207,-191,-205,-206,-190,-188,-185,-147,-150,-189,-221,-204,-203,320,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,329,-221,-192,-200,-201,-151,-186,-148,347,-165,]),} - -_lr_action = { } -for _k, _v in _lr_action_items.items(): - for _x,_y in zip(_v[0],_v[1]): - if not _x in _lr_action: _lr_action[_x] = { } - _lr_action[_x][_k] = _y -del _lr_action_items - -_lr_goto_items = {'storage_class_specifier':([0,1,12,20,36,41,53,64,72,131,186,195,212,258,287,],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,]),'identifier_list_opt':([53,],[112,]),'selection_statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[228,228,228,228,228,228,228,228,228,228,228,228,228,]),'constant':([52,88,92,94,98,100,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,]),'unary_expression':([52,88,92,94,98,100,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[82,147,82,156,157,163,157,157,82,157,157,157,157,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,157,82,82,82,82,157,157,157,157,82,157,82,157,82,157,82,157,157,157,157,157,157,157,157,82,157,157,157,157,157,157,157,157,157,157,]),'conditional_expression':([52,98,128,131,143,146,151,152,155,180,189,199,204,212,213,217,221,227,232,251,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[109,161,161,161,109,161,161,161,161,161,109,109,161,161,161,161,109,161,109,161,161,109,161,161,161,161,161,161,161,161,346,161,161,161,161,161,161,161,161,161,161,]),'struct_or_union_specifier':([0,1,12,20,36,41,47,53,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,]),'initializer':([128,204,332,],[202,296,349,]),'abstract_declarator_opt':([116,160,],[187,257,]),'iteration_statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[207,207,207,207,207,207,207,207,207,207,207,207,207,]),'init_declarator_list':([26,69,],[61,61,]),'init_declarator_list_opt':([26,69,],[62,62,]),'struct_declaration_list':([47,74,80,],[75,134,145,]),'enumerator':([55,120,124,198,],[121,121,121,293,]),'pp_directive':([0,20,],[10,10,]),'abstract_declarator':([116,160,186,258,],[188,188,284,284,]),'declaration_specifiers_opt':([1,12,36,],[42,49,67,]),'external_declaration':([0,20,],[11,51,]),'type_specifier':([0,1,12,20,36,41,47,53,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[12,12,12,12,12,12,76,12,12,12,76,76,76,76,76,76,12,76,76,76,12,12,12,12,12,]),'compound_statement':([71,129,131,212,217,227,301,309,315,340,352,354,356,364,367,],[132,205,214,214,214,214,214,214,214,214,214,214,214,214,214,]),'pointer':([0,4,20,26,58,69,79,116,127,160,186,234,258,],[13,13,13,13,126,13,13,192,13,259,192,13,259,]),'type_name':([98,146,],[158,237,]),'postfix_expression':([52,88,92,94,98,100,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,]),'parameter_type_list_opt':([186,258,287,],[283,283,331,]),'expression_statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[206,206,206,206,206,206,206,206,206,206,206,206,206,]),'unary_operator':([52,88,92,94,98,100,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,]),'cast_expression':([52,92,98,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[99,154,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,324,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'initializer_list':([204,],[297,]),'struct_declarator_list':([79,],[144,]),'empty':([1,12,25,26,36,41,52,53,64,69,76,78,116,131,160,186,189,212,217,227,258,286,287,301,306,309,315,340,351,352,354,356,362,364,367,],[43,43,60,63,43,68,93,113,68,63,137,137,193,226,193,281,93,302,302,302,281,93,281,302,302,302,302,302,302,302,302,302,302,302,302,]),'assignment_operator':([157,],[251,]),'struct_or_union':([0,1,12,20,36,41,47,53,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,]),'struct_declaration':([47,74,75,80,134,145,],[77,77,135,77,135,135,]),'assignment_expression':([98,128,131,146,151,152,155,180,204,212,213,217,227,251,261,301,306,309,310,312,315,316,322,332,340,351,352,354,355,356,362,364,367,],[159,203,159,159,159,241,159,159,203,159,159,159,159,323,325,159,159,159,159,159,159,159,345,203,159,159,159,159,159,159,159,159,159,]),'parameter_type_list':([53,186,258,287,],[114,282,282,282,]),'type_qualifier_list_opt':([25,],[58,]),'direct_declarator':([0,4,13,20,26,69,79,116,127,186,192,234,],[23,23,50,23,23,23,23,23,23,23,50,23,]),'type_qualifier_list':([25,],[57,]),'argument_expression_list':([152,],[243,]),'statement_list_opt':([131,],[209,]),'direct_abstract_declarator':([116,160,186,192,258,259,],[191,191,191,288,191,288,]),'specifier_qualifier_list_opt':([76,78,],[138,140,]),'constant_expression':([52,143,189,199,221,232,286,],[108,233,108,294,311,317,108,]),'expression_opt':([131,212,217,227,301,306,309,315,340,351,352,354,356,362,364,367,],[210,210,210,210,210,337,210,210,210,357,210,210,210,365,210,210,]),'primary_expression':([52,88,92,94,98,100,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'declaration_specifiers':([0,1,12,20,36,41,53,64,72,131,186,195,212,258,287,],[26,44,44,26,44,69,116,69,69,69,116,116,69,116,116,]),'declaration':([0,20,41,64,72,131,212,],[27,27,70,70,133,70,133,]),'declarator':([0,4,20,26,69,79,116,127,186,234,],[41,45,41,64,130,142,190,130,45,142,]),'typedef_name':([0,1,12,20,36,41,47,53,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,]),'identifier_list':([53,],[117,]),'jump_statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[224,224,224,224,224,224,224,224,224,224,224,224,224,]),'declaration_list_opt':([41,64,],[71,129,]),'struct_declarator':([79,234,],[141,318,]),'function_definition':([0,20,],[30,30,]),'binary_expression':([52,98,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[104,104,104,104,104,104,104,104,104,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,104,279,280,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'parameter_list':([53,186,258,287,],[118,118,118,118,]),'enum_specifier':([0,1,12,20,36,41,47,53,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,]),'decl_body':([0,20,41,64,72,131,212,],[35,35,35,35,35,35,35,]),'type_qualifier':([0,1,12,20,25,36,41,47,53,57,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[36,36,36,36,59,36,36,78,36,125,36,36,78,78,78,78,78,78,36,78,78,78,36,36,36,36,36,]),'constant_expression_opt':([52,189,286,],[105,285,330,]),'enumerator_list':([55,120,124,],[122,196,200,]),'labeled_statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[211,211,211,211,211,211,211,211,211,211,211,211,211,]),'declaration_list':([41,64,131,],[72,72,212,]),'specifier_qualifier_list':([47,74,75,76,78,80,98,134,145,146,],[79,79,79,139,139,79,160,79,79,160,]),'statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[223,223,308,314,308,338,343,353,358,359,361,366,368,]),'translation_unit':([0,],[20,]),'init_declarator':([26,69,127,],[65,65,201,]),'parameter_declaration':([53,186,195,258,287,],[115,115,291,115,115,]),'identifier':([52,53,88,92,94,98,100,128,131,143,146,148,150,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,194,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[111,119,111,111,111,111,111,111,111,111,111,238,239,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,289,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,]),'expression':([98,131,146,151,155,180,212,213,217,227,301,306,309,310,312,315,316,340,351,352,354,355,356,362,364,367,],[162,218,162,240,162,278,218,305,218,218,218,218,218,339,341,218,344,218,218,218,218,360,218,218,218,218,]),'statement_list':([131,212,],[217,301,]),} - -_lr_goto = { } -for _k, _v in _lr_goto_items.items(): - for _x,_y in zip(_v[0],_v[1]): - if not _x in _lr_goto: _lr_goto[_x] = { } - _lr_goto[_x][_k] = _y -del _lr_goto_items -_lr_productions = [ - ("S' -> translation_unit","S'",1,None,None,None), - ('abstract_declarator_opt -> empty','abstract_declarator_opt',1,'p_abstract_declarator_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('abstract_declarator_opt -> abstract_declarator','abstract_declarator_opt',1,'p_abstract_declarator_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('constant_expression_opt -> empty','constant_expression_opt',1,'p_constant_expression_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('constant_expression_opt -> constant_expression','constant_expression_opt',1,'p_constant_expression_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('declaration_list_opt -> empty','declaration_list_opt',1,'p_declaration_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('declaration_list_opt -> declaration_list','declaration_list_opt',1,'p_declaration_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('declaration_specifiers_opt -> empty','declaration_specifiers_opt',1,'p_declaration_specifiers_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('declaration_specifiers_opt -> declaration_specifiers','declaration_specifiers_opt',1,'p_declaration_specifiers_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('expression_opt -> empty','expression_opt',1,'p_expression_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('expression_opt -> expression','expression_opt',1,'p_expression_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('identifier_list_opt -> empty','identifier_list_opt',1,'p_identifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('identifier_list_opt -> identifier_list','identifier_list_opt',1,'p_identifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('init_declarator_list_opt -> empty','init_declarator_list_opt',1,'p_init_declarator_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('init_declarator_list_opt -> init_declarator_list','init_declarator_list_opt',1,'p_init_declarator_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('parameter_type_list_opt -> empty','parameter_type_list_opt',1,'p_parameter_type_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('parameter_type_list_opt -> parameter_type_list','parameter_type_list_opt',1,'p_parameter_type_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('specifier_qualifier_list_opt -> empty','specifier_qualifier_list_opt',1,'p_specifier_qualifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('specifier_qualifier_list_opt -> specifier_qualifier_list','specifier_qualifier_list_opt',1,'p_specifier_qualifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('statement_list_opt -> empty','statement_list_opt',1,'p_statement_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('statement_list_opt -> statement_list','statement_list_opt',1,'p_statement_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('type_qualifier_list_opt -> empty','type_qualifier_list_opt',1,'p_type_qualifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('type_qualifier_list_opt -> type_qualifier_list','type_qualifier_list_opt',1,'p_type_qualifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('translation_unit -> external_declaration','translation_unit',1,'p_translation_unit_1','/home/skybot/ext/parser/pycparser/c_parser.py',333), - ('translation_unit -> translation_unit external_declaration','translation_unit',2,'p_translation_unit_2','/home/skybot/ext/parser/pycparser/c_parser.py',340), - ('external_declaration -> function_definition','external_declaration',1,'p_external_declaration_1','/home/skybot/ext/parser/pycparser/c_parser.py',351), - ('external_declaration -> declaration','external_declaration',1,'p_external_declaration_2','/home/skybot/ext/parser/pycparser/c_parser.py',356), - ('external_declaration -> pp_directive','external_declaration',1,'p_external_declaration_3','/home/skybot/ext/parser/pycparser/c_parser.py',361), - ('pp_directive -> PPHASH','pp_directive',1,'p_pp_directive','/home/skybot/ext/parser/pycparser/c_parser.py',366), - ('function_definition -> declarator declaration_list_opt compound_statement','function_definition',3,'p_function_definition_1','/home/skybot/ext/parser/pycparser/c_parser.py',375), - ('function_definition -> declaration_specifiers declarator declaration_list_opt compound_statement','function_definition',4,'p_function_definition_2','/home/skybot/ext/parser/pycparser/c_parser.py',387), - ('statement -> labeled_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',398), - ('statement -> expression_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',399), - ('statement -> compound_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',400), - ('statement -> selection_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',401), - ('statement -> iteration_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',402), - ('statement -> jump_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',403), - ('decl_body -> declaration_specifiers init_declarator_list_opt','decl_body',2,'p_decl_body','/home/skybot/ext/parser/pycparser/c_parser.py',417), - ('declaration -> decl_body SEMI','declaration',2,'p_declaration','/home/skybot/ext/parser/pycparser/c_parser.py',497), - ('declaration_list -> declaration','declaration_list',1,'p_declaration_list','/home/skybot/ext/parser/pycparser/c_parser.py',506), - ('declaration_list -> declaration_list declaration','declaration_list',2,'p_declaration_list','/home/skybot/ext/parser/pycparser/c_parser.py',507), - ('declaration_specifiers -> type_qualifier declaration_specifiers_opt','declaration_specifiers',2,'p_declaration_specifiers_1','/home/skybot/ext/parser/pycparser/c_parser.py',512), - ('declaration_specifiers -> type_specifier declaration_specifiers_opt','declaration_specifiers',2,'p_declaration_specifiers_2','/home/skybot/ext/parser/pycparser/c_parser.py',517), - ('declaration_specifiers -> storage_class_specifier declaration_specifiers_opt','declaration_specifiers',2,'p_declaration_specifiers_3','/home/skybot/ext/parser/pycparser/c_parser.py',522), - ('storage_class_specifier -> AUTO','storage_class_specifier',1,'p_storage_class_specifier','/home/skybot/ext/parser/pycparser/c_parser.py',527), - ('storage_class_specifier -> REGISTER','storage_class_specifier',1,'p_storage_class_specifier','/home/skybot/ext/parser/pycparser/c_parser.py',528), - ('storage_class_specifier -> STATIC','storage_class_specifier',1,'p_storage_class_specifier','/home/skybot/ext/parser/pycparser/c_parser.py',529), - ('storage_class_specifier -> EXTERN','storage_class_specifier',1,'p_storage_class_specifier','/home/skybot/ext/parser/pycparser/c_parser.py',530), - ('storage_class_specifier -> TYPEDEF','storage_class_specifier',1,'p_storage_class_specifier','/home/skybot/ext/parser/pycparser/c_parser.py',531), - ('type_specifier -> VOID','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',536), - ('type_specifier -> CHAR','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',537), - ('type_specifier -> SHORT','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',538), - ('type_specifier -> INT','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',539), - ('type_specifier -> LONG','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',540), - ('type_specifier -> FLOAT','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',541), - ('type_specifier -> DOUBLE','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',542), - ('type_specifier -> SIGNED','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',543), - ('type_specifier -> UNSIGNED','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',544), - ('type_specifier -> typedef_name','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',545), - ('type_specifier -> enum_specifier','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',546), - ('type_specifier -> struct_or_union_specifier','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',547), - ('type_qualifier -> CONST','type_qualifier',1,'p_type_qualifier','/home/skybot/ext/parser/pycparser/c_parser.py',552), - ('type_qualifier -> VOLATILE','type_qualifier',1,'p_type_qualifier','/home/skybot/ext/parser/pycparser/c_parser.py',553), - ('init_declarator_list -> init_declarator','init_declarator_list',1,'p_init_declarator_list','/home/skybot/ext/parser/pycparser/c_parser.py',558), - ('init_declarator_list -> init_declarator_list COMMA init_declarator','init_declarator_list',3,'p_init_declarator_list','/home/skybot/ext/parser/pycparser/c_parser.py',559), - ('init_declarator -> declarator','init_declarator',1,'p_init_declarator','/home/skybot/ext/parser/pycparser/c_parser.py',567), - ('init_declarator -> declarator EQUALS initializer','init_declarator',3,'p_init_declarator','/home/skybot/ext/parser/pycparser/c_parser.py',568), - ('specifier_qualifier_list -> type_qualifier specifier_qualifier_list_opt','specifier_qualifier_list',2,'p_specifier_qualifier_list_1','/home/skybot/ext/parser/pycparser/c_parser.py',573), - ('specifier_qualifier_list -> type_specifier specifier_qualifier_list_opt','specifier_qualifier_list',2,'p_specifier_qualifier_list_2','/home/skybot/ext/parser/pycparser/c_parser.py',578), - ('struct_or_union_specifier -> struct_or_union ID','struct_or_union_specifier',2,'p_struct_or_union_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',586), - ('struct_or_union_specifier -> struct_or_union TYPEID','struct_or_union_specifier',2,'p_struct_or_union_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',587), - ('struct_or_union_specifier -> struct_or_union LBRACE struct_declaration_list RBRACE','struct_or_union_specifier',4,'p_struct_or_union_specifier_2','/home/skybot/ext/parser/pycparser/c_parser.py',596), - ('struct_or_union_specifier -> struct_or_union ID LBRACE struct_declaration_list RBRACE','struct_or_union_specifier',5,'p_struct_or_union_specifier_3','/home/skybot/ext/parser/pycparser/c_parser.py',605), - ('struct_or_union_specifier -> struct_or_union TYPEID LBRACE struct_declaration_list RBRACE','struct_or_union_specifier',5,'p_struct_or_union_specifier_3','/home/skybot/ext/parser/pycparser/c_parser.py',606), - ('struct_or_union -> STRUCT','struct_or_union',1,'p_struct_or_union','/home/skybot/ext/parser/pycparser/c_parser.py',615), - ('struct_or_union -> UNION','struct_or_union',1,'p_struct_or_union','/home/skybot/ext/parser/pycparser/c_parser.py',616), - ('struct_declaration_list -> struct_declaration','struct_declaration_list',1,'p_struct_declaration_list','/home/skybot/ext/parser/pycparser/c_parser.py',623), - ('struct_declaration_list -> struct_declaration_list struct_declaration','struct_declaration_list',2,'p_struct_declaration_list','/home/skybot/ext/parser/pycparser/c_parser.py',624), - ('struct_declaration -> specifier_qualifier_list struct_declarator_list SEMI','struct_declaration',3,'p_struct_declaration_1','/home/skybot/ext/parser/pycparser/c_parser.py',629), - ('struct_declarator_list -> struct_declarator','struct_declarator_list',1,'p_struct_declarator_list','/home/skybot/ext/parser/pycparser/c_parser.py',650), - ('struct_declarator_list -> struct_declarator_list COMMA struct_declarator','struct_declarator_list',3,'p_struct_declarator_list','/home/skybot/ext/parser/pycparser/c_parser.py',651), - ('struct_declarator -> declarator','struct_declarator',1,'p_struct_declarator_1','/home/skybot/ext/parser/pycparser/c_parser.py',659), - ('struct_declarator -> declarator COLON constant_expression','struct_declarator',3,'p_struct_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',664), - ('struct_declarator -> COLON constant_expression','struct_declarator',2,'p_struct_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',665), - ('enum_specifier -> ENUM ID','enum_specifier',2,'p_enum_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',673), - ('enum_specifier -> ENUM TYPEID','enum_specifier',2,'p_enum_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',674), - ('enum_specifier -> ENUM LBRACE enumerator_list RBRACE','enum_specifier',4,'p_enum_specifier_2','/home/skybot/ext/parser/pycparser/c_parser.py',679), - ('enum_specifier -> ENUM ID LBRACE enumerator_list RBRACE','enum_specifier',5,'p_enum_specifier_3','/home/skybot/ext/parser/pycparser/c_parser.py',684), - ('enum_specifier -> ENUM TYPEID LBRACE enumerator_list RBRACE','enum_specifier',5,'p_enum_specifier_3','/home/skybot/ext/parser/pycparser/c_parser.py',685), - ('enumerator_list -> enumerator','enumerator_list',1,'p_enumerator_list','/home/skybot/ext/parser/pycparser/c_parser.py',690), - ('enumerator_list -> enumerator_list COMMA','enumerator_list',2,'p_enumerator_list','/home/skybot/ext/parser/pycparser/c_parser.py',691), - ('enumerator_list -> enumerator_list COMMA enumerator','enumerator_list',3,'p_enumerator_list','/home/skybot/ext/parser/pycparser/c_parser.py',692), - ('enumerator -> ID','enumerator',1,'p_enumerator','/home/skybot/ext/parser/pycparser/c_parser.py',703), - ('enumerator -> ID EQUALS constant_expression','enumerator',3,'p_enumerator','/home/skybot/ext/parser/pycparser/c_parser.py',704), - ('declarator -> direct_declarator','declarator',1,'p_declarator_1','/home/skybot/ext/parser/pycparser/c_parser.py',716), - ('declarator -> pointer direct_declarator','declarator',2,'p_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',721), - ('direct_declarator -> ID','direct_declarator',1,'p_direct_declarator_1','/home/skybot/ext/parser/pycparser/c_parser.py',726), - ('direct_declarator -> LPAREN declarator RPAREN','direct_declarator',3,'p_direct_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',735), - ('direct_declarator -> direct_declarator LBRACKET constant_expression_opt RBRACKET','direct_declarator',4,'p_direct_declarator_3','/home/skybot/ext/parser/pycparser/c_parser.py',740), - ('direct_declarator -> direct_declarator LPAREN parameter_type_list RPAREN','direct_declarator',4,'p_direct_declarator_4','/home/skybot/ext/parser/pycparser/c_parser.py',750), - ('direct_declarator -> direct_declarator LPAREN identifier_list_opt RPAREN','direct_declarator',4,'p_direct_declarator_4','/home/skybot/ext/parser/pycparser/c_parser.py',751), - ('pointer -> TIMES type_qualifier_list_opt','pointer',2,'p_pointer','/home/skybot/ext/parser/pycparser/c_parser.py',761), - ('pointer -> TIMES type_qualifier_list_opt pointer','pointer',3,'p_pointer','/home/skybot/ext/parser/pycparser/c_parser.py',762), - ('type_qualifier_list -> type_qualifier','type_qualifier_list',1,'p_type_qualifier_list','/home/skybot/ext/parser/pycparser/c_parser.py',772), - ('type_qualifier_list -> type_qualifier_list type_qualifier','type_qualifier_list',2,'p_type_qualifier_list','/home/skybot/ext/parser/pycparser/c_parser.py',773), - ('parameter_type_list -> parameter_list','parameter_type_list',1,'p_parameter_type_list','/home/skybot/ext/parser/pycparser/c_parser.py',778), - ('parameter_type_list -> parameter_list COMMA ELLIPSIS','parameter_type_list',3,'p_parameter_type_list','/home/skybot/ext/parser/pycparser/c_parser.py',779), - ('parameter_list -> parameter_declaration','parameter_list',1,'p_parameter_list','/home/skybot/ext/parser/pycparser/c_parser.py',787), - ('parameter_list -> parameter_list COMMA parameter_declaration','parameter_list',3,'p_parameter_list','/home/skybot/ext/parser/pycparser/c_parser.py',788), - ('parameter_declaration -> declaration_specifiers declarator','parameter_declaration',2,'p_parameter_declaration_1','/home/skybot/ext/parser/pycparser/c_parser.py',797), - ('parameter_declaration -> declaration_specifiers abstract_declarator_opt','parameter_declaration',2,'p_parameter_declaration_2','/home/skybot/ext/parser/pycparser/c_parser.py',815), - ('identifier_list -> identifier','identifier_list',1,'p_identifier_list','/home/skybot/ext/parser/pycparser/c_parser.py',827), - ('identifier_list -> identifier_list COMMA identifier','identifier_list',3,'p_identifier_list','/home/skybot/ext/parser/pycparser/c_parser.py',828), - ('initializer -> assignment_expression','initializer',1,'p_initializer_1','/home/skybot/ext/parser/pycparser/c_parser.py',837), - ('initializer -> LBRACE initializer_list RBRACE','initializer',3,'p_initializer_2','/home/skybot/ext/parser/pycparser/c_parser.py',842), - ('initializer -> LBRACE initializer_list COMMA RBRACE','initializer',4,'p_initializer_2','/home/skybot/ext/parser/pycparser/c_parser.py',843), - ('initializer_list -> initializer','initializer_list',1,'p_initializer_list','/home/skybot/ext/parser/pycparser/c_parser.py',848), - ('initializer_list -> initializer_list COMMA initializer','initializer_list',3,'p_initializer_list','/home/skybot/ext/parser/pycparser/c_parser.py',849), - ('type_name -> specifier_qualifier_list abstract_declarator_opt','type_name',2,'p_type_name','/home/skybot/ext/parser/pycparser/c_parser.py',858), - ('abstract_declarator -> pointer','abstract_declarator',1,'p_abstract_declarator_1','/home/skybot/ext/parser/pycparser/c_parser.py',873), - ('abstract_declarator -> pointer direct_abstract_declarator','abstract_declarator',2,'p_abstract_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',881), - ('abstract_declarator -> direct_abstract_declarator','abstract_declarator',1,'p_abstract_declarator_3','/home/skybot/ext/parser/pycparser/c_parser.py',886), - ('direct_abstract_declarator -> LPAREN abstract_declarator RPAREN','direct_abstract_declarator',3,'p_direct_abstract_declarator_1','/home/skybot/ext/parser/pycparser/c_parser.py',896), - ('direct_abstract_declarator -> direct_abstract_declarator LBRACKET constant_expression_opt RBRACKET','direct_abstract_declarator',4,'p_direct_abstract_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',900), - ('direct_abstract_declarator -> LBRACKET constant_expression_opt RBRACKET','direct_abstract_declarator',3,'p_direct_abstract_declarator_3','/home/skybot/ext/parser/pycparser/c_parser.py',910), - ('direct_abstract_declarator -> direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN','direct_abstract_declarator',4,'p_direct_abstract_declarator_4','/home/skybot/ext/parser/pycparser/c_parser.py',918), - ('direct_abstract_declarator -> LPAREN parameter_type_list_opt RPAREN','direct_abstract_declarator',3,'p_direct_abstract_declarator_5','/home/skybot/ext/parser/pycparser/c_parser.py',928), - ('compound_statement -> LBRACE statement_list_opt RBRACE','compound_statement',3,'p_compound_statement_1','/home/skybot/ext/parser/pycparser/c_parser.py',936), - ('compound_statement -> LBRACE declaration_list RBRACE','compound_statement',3,'p_compound_statement_2','/home/skybot/ext/parser/pycparser/c_parser.py',943), - ('compound_statement -> LBRACE declaration_list statement_list RBRACE','compound_statement',4,'p_compound_statement_3','/home/skybot/ext/parser/pycparser/c_parser.py',950), - ('statement_list -> statement','statement_list',1,'p_statement_list','/home/skybot/ext/parser/pycparser/c_parser.py',964), - ('statement_list -> statement_list statement','statement_list',2,'p_statement_list','/home/skybot/ext/parser/pycparser/c_parser.py',965), - ('labeled_statement -> ID COLON statement','labeled_statement',3,'p_labeled_statement_1','/home/skybot/ext/parser/pycparser/c_parser.py',973), - ('labeled_statement -> CASE constant_expression COLON statement','labeled_statement',4,'p_labeled_statement_2','/home/skybot/ext/parser/pycparser/c_parser.py',977), - ('labeled_statement -> DEFAULT COLON statement','labeled_statement',3,'p_labeled_statement_3','/home/skybot/ext/parser/pycparser/c_parser.py',981), - ('selection_statement -> IF LPAREN expression RPAREN statement','selection_statement',5,'p_selection_statement_1','/home/skybot/ext/parser/pycparser/c_parser.py',985), - ('selection_statement -> IF LPAREN expression RPAREN statement ELSE statement','selection_statement',7,'p_selection_statement_2','/home/skybot/ext/parser/pycparser/c_parser.py',989), - ('selection_statement -> SWITCH LPAREN expression RPAREN statement','selection_statement',5,'p_selection_statement_3','/home/skybot/ext/parser/pycparser/c_parser.py',993), - ('iteration_statement -> WHILE LPAREN expression RPAREN statement','iteration_statement',5,'p_iteration_statement_1','/home/skybot/ext/parser/pycparser/c_parser.py',997), - ('iteration_statement -> DO statement WHILE LPAREN expression RPAREN','iteration_statement',6,'p_iteration_statement_2','/home/skybot/ext/parser/pycparser/c_parser.py',1001), - ('iteration_statement -> FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN statement','iteration_statement',9,'p_iteration_statement_3','/home/skybot/ext/parser/pycparser/c_parser.py',1005), - ('jump_statement -> GOTO ID SEMI','jump_statement',3,'p_jump_statement_1','/home/skybot/ext/parser/pycparser/c_parser.py',1009), - ('jump_statement -> BREAK SEMI','jump_statement',2,'p_jump_statement_2','/home/skybot/ext/parser/pycparser/c_parser.py',1013), - ('jump_statement -> CONTINUE SEMI','jump_statement',2,'p_jump_statement_3','/home/skybot/ext/parser/pycparser/c_parser.py',1017), - ('jump_statement -> RETURN expression SEMI','jump_statement',3,'p_jump_statement_4','/home/skybot/ext/parser/pycparser/c_parser.py',1021), - ('jump_statement -> RETURN SEMI','jump_statement',2,'p_jump_statement_4','/home/skybot/ext/parser/pycparser/c_parser.py',1022), - ('expression_statement -> expression_opt SEMI','expression_statement',2,'p_expression_statement','/home/skybot/ext/parser/pycparser/c_parser.py',1027), - ('expression -> assignment_expression','expression',1,'p_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1031), - ('expression -> expression COMMA assignment_expression','expression',3,'p_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1032), - ('typedef_name -> TYPEID','typedef_name',1,'p_typedef_name','/home/skybot/ext/parser/pycparser/c_parser.py',1044), - ('assignment_expression -> conditional_expression','assignment_expression',1,'p_assignment_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1048), - ('assignment_expression -> unary_expression assignment_operator assignment_expression','assignment_expression',3,'p_assignment_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1049), - ('assignment_operator -> EQUALS','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1062), - ('assignment_operator -> XOREQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1063), - ('assignment_operator -> TIMESEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1064), - ('assignment_operator -> DIVEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1065), - ('assignment_operator -> MODEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1066), - ('assignment_operator -> PLUSEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1067), - ('assignment_operator -> MINUSEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1068), - ('assignment_operator -> LSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1069), - ('assignment_operator -> RSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1070), - ('assignment_operator -> ANDEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1071), - ('assignment_operator -> OREQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1072), - ('constant_expression -> conditional_expression','constant_expression',1,'p_constant_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1077), - ('conditional_expression -> binary_expression','conditional_expression',1,'p_conditional_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1081), - ('conditional_expression -> binary_expression CONDOP expression COLON conditional_expression','conditional_expression',5,'p_conditional_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1082), - ('binary_expression -> cast_expression','binary_expression',1,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1090), - ('binary_expression -> binary_expression TIMES binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1091), - ('binary_expression -> binary_expression DIVIDE binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1092), - ('binary_expression -> binary_expression MOD binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1093), - ('binary_expression -> binary_expression PLUS binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1094), - ('binary_expression -> binary_expression MINUS binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1095), - ('binary_expression -> binary_expression RSHIFT binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1096), - ('binary_expression -> binary_expression LSHIFT binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1097), - ('binary_expression -> binary_expression LT binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1098), - ('binary_expression -> binary_expression LE binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1099), - ('binary_expression -> binary_expression GE binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1100), - ('binary_expression -> binary_expression GT binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1101), - ('binary_expression -> binary_expression EQ binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1102), - ('binary_expression -> binary_expression NE binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1103), - ('binary_expression -> binary_expression AND binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1104), - ('binary_expression -> binary_expression OR binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1105), - ('binary_expression -> binary_expression XOR binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1106), - ('binary_expression -> binary_expression LAND binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1107), - ('binary_expression -> binary_expression LOR binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1108), - ('cast_expression -> unary_expression','cast_expression',1,'p_cast_expression_1','/home/skybot/ext/parser/pycparser/c_parser.py',1116), - ('cast_expression -> LPAREN type_name RPAREN cast_expression','cast_expression',4,'p_cast_expression_2','/home/skybot/ext/parser/pycparser/c_parser.py',1120), - ('unary_expression -> postfix_expression','unary_expression',1,'p_unary_expression_1','/home/skybot/ext/parser/pycparser/c_parser.py',1124), - ('unary_expression -> PLUSPLUS unary_expression','unary_expression',2,'p_unary_expression_2','/home/skybot/ext/parser/pycparser/c_parser.py',1128), - ('unary_expression -> MINUSMINUS unary_expression','unary_expression',2,'p_unary_expression_2','/home/skybot/ext/parser/pycparser/c_parser.py',1129), - ('unary_expression -> unary_operator cast_expression','unary_expression',2,'p_unary_expression_2','/home/skybot/ext/parser/pycparser/c_parser.py',1130), - ('unary_expression -> SIZEOF unary_expression','unary_expression',2,'p_unary_expression_3','/home/skybot/ext/parser/pycparser/c_parser.py',1135), - ('unary_expression -> SIZEOF LPAREN type_name RPAREN','unary_expression',4,'p_unary_expression_3','/home/skybot/ext/parser/pycparser/c_parser.py',1136), - ('unary_operator -> AND','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1144), - ('unary_operator -> TIMES','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1145), - ('unary_operator -> PLUS','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1146), - ('unary_operator -> MINUS','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1147), - ('unary_operator -> NOT','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1148), - ('unary_operator -> LNOT','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1149), - ('postfix_expression -> primary_expression','postfix_expression',1,'p_postfix_exptession_1','/home/skybot/ext/parser/pycparser/c_parser.py',1154), - ('postfix_expression -> postfix_expression LBRACKET expression RBRACKET','postfix_expression',4,'p_postfix_exptession_2','/home/skybot/ext/parser/pycparser/c_parser.py',1158), - ('postfix_expression -> postfix_expression LPAREN argument_expression_list RPAREN','postfix_expression',4,'p_postfix_exptession_3','/home/skybot/ext/parser/pycparser/c_parser.py',1162), - ('postfix_expression -> postfix_expression LPAREN RPAREN','postfix_expression',3,'p_postfix_exptession_3','/home/skybot/ext/parser/pycparser/c_parser.py',1163), - ('postfix_expression -> postfix_expression PERIOD identifier','postfix_expression',3,'p_postfix_expression_4','/home/skybot/ext/parser/pycparser/c_parser.py',1168), - ('postfix_expression -> postfix_expression ARROW identifier','postfix_expression',3,'p_postfix_expression_4','/home/skybot/ext/parser/pycparser/c_parser.py',1169), - ('postfix_expression -> postfix_expression PLUSPLUS','postfix_expression',2,'p_postfix_expression_5','/home/skybot/ext/parser/pycparser/c_parser.py',1174), - ('postfix_expression -> postfix_expression MINUSMINUS','postfix_expression',2,'p_postfix_expression_5','/home/skybot/ext/parser/pycparser/c_parser.py',1175), - ('primary_expression -> identifier','primary_expression',1,'p_primary_expression_1','/home/skybot/ext/parser/pycparser/c_parser.py',1180), - ('primary_expression -> constant','primary_expression',1,'p_primary_expression_2','/home/skybot/ext/parser/pycparser/c_parser.py',1184), - ('primary_expression -> STRING_LITERAL','primary_expression',1,'p_primary_expression_3','/home/skybot/ext/parser/pycparser/c_parser.py',1188), - ('primary_expression -> WSTRING_LITERAL','primary_expression',1,'p_primary_expression_3','/home/skybot/ext/parser/pycparser/c_parser.py',1189), - ('primary_expression -> LPAREN expression RPAREN','primary_expression',3,'p_primary_expression_4','/home/skybot/ext/parser/pycparser/c_parser.py',1195), - ('argument_expression_list -> assignment_expression','argument_expression_list',1,'p_argument_expression_list','/home/skybot/ext/parser/pycparser/c_parser.py',1199), - ('argument_expression_list -> argument_expression_list COMMA assignment_expression','argument_expression_list',3,'p_argument_expression_list','/home/skybot/ext/parser/pycparser/c_parser.py',1200), - ('identifier -> ID','identifier',1,'p_identifier','/home/skybot/ext/parser/pycparser/c_parser.py',1209), - ('constant -> INT_CONST_DEC','constant',1,'p_constant_1','/home/skybot/ext/parser/pycparser/c_parser.py',1213), - ('constant -> INT_CONST_OCT','constant',1,'p_constant_1','/home/skybot/ext/parser/pycparser/c_parser.py',1214), - ('constant -> INT_CONST_HEX','constant',1,'p_constant_1','/home/skybot/ext/parser/pycparser/c_parser.py',1215), - ('constant -> FLOAT_CONST','constant',1,'p_constant_2','/home/skybot/ext/parser/pycparser/c_parser.py',1221), - ('constant -> CHAR_CONST','constant',1,'p_constant_3','/home/skybot/ext/parser/pycparser/c_parser.py',1226), - ('constant -> WCHAR_CONST','constant',1,'p_constant_3','/home/skybot/ext/parser/pycparser/c_parser.py',1227), - ('empty -> ','empty',0,'p_empty','/home/skybot/ext/parser/pycparser/c_parser.py',1233), -] diff --git a/plugins_available/pyexec.py b/plugins_available/pyexec.py deleted file mode 100644 index f6e3e78..0000000 --- a/plugins_available/pyexec.py +++ /dev/null @@ -1,25 +0,0 @@ -import urllib -import re - -from util import hook - - -re_lineends = re.compile(r'[\r\n]*') - - -@hook.command -def py(inp): - ".py -- executes python code " - - if not inp: - return py.__doc__ - - res = urllib.urlopen("http://eval.appspot.com/eval?statement=%s" % - urllib.quote(inp.strip(), safe='')).readlines() - if len(res) == 0: - return - res[0] = re_lineends.split(res[0])[0] - if not res[0] == 'Traceback (most recent call last):': - return res[0] - else: - return res[-1] diff --git a/plugins_available/remember.py b/plugins_available/remember.py deleted file mode 100644 index 4d2904e..0000000 --- a/plugins_available/remember.py +++ /dev/null @@ -1,89 +0,0 @@ -""" -remember.py: written by Scaevolus 2009 -""" - -import os -import thread -import codecs - -from util import hook - - -lock = thread.allocate_lock() -memory = {} - - -def load_memory(filename, mtimes={}): - if not os.path.exists(filename): - return {} - mtime = os.stat(filename).st_mtime - if mtimes.get(filename, 0) != mtime: - mtimes[filename] = mtime - return dict((x.split(None, 1)[0].lower(), x.strip()) for x in - codecs.open(filename, 'r', 'utf-8')) - - -def save_memory(filename, memory): - out = codecs.open(filename, 'w', 'utf-8') - out.write('\n'.join(sorted(memory.itervalues()))) - out.flush() - out.close() - - -def make_filename(dir, chan): - return os.path.join(dir, 'memory') - - -@hook.command -def remember(bot, input): - ".remember -- maps word to data in the memory" - with lock: - filename = make_filename(bot.persist_dir, input.chan) - memory.setdefault(filename, load_memory(filename)) - - try: - head, tail = input.inp.split(None, 1) - except ValueError: - return remember.__doc__ - - tail = tail.strip() - low = head.lower() - if low not in memory[filename]: - input.reply("done.") - else: - input.reply('forgetting that "%s", remembering this instead.' % - memory[filename][low]) - memory[filename][low] = input.inp.strip() - save_memory(filename, memory[filename]) - - -@hook.command -def forget(bot, input): - ".forget -- forgets the mapping that word had" - with lock: - filename = make_filename(bot.persist_dir, input.chan) - memory.setdefault(filename, load_memory(filename)) - - if not input.inp.strip(): - return forget.__doc__ - - low = input.inp.strip().lower() - if low not in memory[filename]: - return "I don't know about that." - if not hasattr(input, 'chan'): - return "I won't forget anything in private." - input.say("Forgot that %s" % memory[filename][low]) - del memory[filename][low] - save_memory(filename, memory[filename]) - - -@hook.command(hook='\?(.+)', prefix=False) -def question(bot, input): - "? -- shows what data is associated with word" - with lock: - filename = make_filename(bot.persist_dir, input.chan) - memory.setdefault(filename, load_memory(filename)) - - word = input.inp.split()[0].lower() - if word in memory[filename]: - input.say("%s" % memory[filename][word]) diff --git a/plugins_available/seen.py b/plugins_available/seen.py deleted file mode 100644 index 64308f5..0000000 --- a/plugins_available/seen.py +++ /dev/null @@ -1,77 +0,0 @@ -" seen.py: written by sklnd in about two beers July 2009" - -import os -import time -from datetime import datetime -import sqlite3 - -from util import hook, timesince - - -dbname = "skybot.db" - - -def adapt_datetime(ts): - return time.mktime(ts.timetuple()) - -sqlite3.register_adapter(datetime, adapt_datetime) - - -@hook.tee -def seeninput(bot, input): - if input.command != 'PRIVMSG': - return - - dbpath = os.path.join(bot.persist_dir, dbname) - - conn = dbconnect(dbpath) - cursor = conn.cursor() - cursor.execute("INSERT OR REPLACE INTO seen(name, date, quote, chan)" - "values(?,?,?,?)", (input.nick.lower(), datetime.now(), - input.msg, input.chan)) - conn.commit() - conn.close() - - -@hook.command -def seen(bot, input): - ".seen -- Tell when a nickname was last in active in irc" - - if len(input.msg) < 6: - return seen.__doc__ - - query = input.inp.strip() - - if query.lower() == input.nick.lower(): - return "Have you looked in a mirror lately?" - - dbpath = os.path.join(bot.persist_dir, dbname) - conn = dbconnect(dbpath) - cursor = conn.cursor() - - command = "SELECT date, quote FROM seen WHERE name LIKE ? AND chan = ?" \ - "ORDER BY date DESC" - cursor.execute(command, (query, input.chan)) - results = cursor.fetchone() - - conn.close() - - if(results != None): - reltime = timesince.timesince(datetime.fromtimestamp(results[0])) - return '%s was last seen %s ago saying: %s' % \ - (query, reltime, results[1]) - else: - return "I've never seen %s" % query - - -def dbconnect(db): - "check to see that our db has the the seen table and return a connection." - conn = sqlite3.connect(db) - - conn.execute("CREATE TABLE IF NOT EXISTS " - "seen(name varchar(30) not null, date datetime not null, " - "quote varchar(250) not null, chan varchar(32) not null, " - "primary key(name, chan));") - conn.commit() - - return conn diff --git a/plugins_available/sieve.py b/plugins_available/sieve.py deleted file mode 100644 index bb3fde3..0000000 --- a/plugins_available/sieve.py +++ /dev/null @@ -1,29 +0,0 @@ -import re - -from util import hook - - -@hook.sieve -def sieve_suite(bot, input, func, args): - events = args.get('events', ['PRIVMSG']) - - if input.command not in events and events != '*': - return None - - if input.nick.lower()[-3:] == 'bot' and args.get('ignorebots', True): - return None - - hook = args.get('hook', r'(.*)') - - if args.get('prefix', True): - # add a prefix, unless it's a private message - hook = (r'^(?:[.!]|' if input.chan != input.nick else r'^(?:[.!]?|') \ - + input.conn.nick + r'[:,]*\s*)' + hook - - input.re = re.match(hook, input.msg, flags=re.I) - if input.re is None: - return None - - input.inp = ' '.join(input.re.groups()) - - return input diff --git a/plugins_available/suggest.py b/plugins_available/suggest.py deleted file mode 100644 index 55cbf12..0000000 --- a/plugins_available/suggest.py +++ /dev/null @@ -1,36 +0,0 @@ -import random -import urllib -import urllib2 -import re -import json - -from util import hook - -@hook.command -def suggest(inp): - ".suggest [#n] -- gets a random/the nth suggested google search" - if not inp.strip(): - return suggest.__doc__ - - m = re.match('^#(\d+) (.+)$', inp) - if m: - num, inp = m.groups() - num = int(num) - if num > 10: - return 'can only get first ten suggestions' - else: - num = 0 - - url = 'http://google.com/complete/search?q=' + urllib.quote(inp, safe='') - page = urllib2.urlopen(url).read() - page_json = page.split('(', 1)[1][:-1] - suggestions = json.loads(page_json)[1] - if not suggestions: - return 'no suggestions found' - if num: - if len(suggestions) + 1 <= num: - return 'only got %d suggestions' % len(suggestions) - out = suggestions[num - 1] - else: - out = random.choice(suggestions) - return '#%d: %s (%s)' % (int(out[2][0]) + 1, out[0], out[1]) diff --git a/plugins_available/tell.py b/plugins_available/tell.py deleted file mode 100644 index bdfc9ec..0000000 --- a/plugins_available/tell.py +++ /dev/null @@ -1,131 +0,0 @@ -" tell.py: written by sklnd in July 2009" - -import os -import time -from datetime import datetime -import sqlite3 - -from util import hook, timesince - - -dbname = "skybot.db" - - -def adapt_datetime(ts): - return time.mktime(ts.timetuple()) - -sqlite3.register_adapter(datetime, adapt_datetime) - - -@hook.command(hook=r'(.*)', prefix=False, ignorebots=True) -def tellinput(bot, input): - dbpath = os.path.join(bot.persist_dir, dbname) - conn = dbconnect(dbpath) - - cursor = conn.cursor() - command = "select count(name) from tell where name LIKE ? and chan = ?" - results = cursor.execute(command, (input.nick, input.chan)).fetchone() - - - if results[0] > 0: - command = "select id, user_from, quote, date from tell " \ - "where name LIKE ? and chan = ? limit 1" - tell = cursor.execute(command, (input.nick, input.chan)).fetchall()[0] - more = results[0] - 1 - reltime = timesince.timesince(datetime.fromtimestamp(tell[3])) - - reply = "%(teller)s said %(reltime)s ago: %(quote)s" % \ - {"teller": tell[1], "quote": tell[2], "reltime": reltime} - if more: - reply += " (+%(more)d more, to view say .showtells)" % {"more": more} - - input.reply(reply) - command = "delete from tell where id = ?" - cursor.execute(command, (tell[0], )) - - conn.commit() - conn.close() - -@hook.command -def showtells(bot, input): - ".showtells -- view all pending tell messages (sent in PM)." - - dbpath = os.path.join(bot.persist_dir, dbname) - conn = dbconnect(dbpath) - - cursor = conn.cursor() - command = "SELECT id, user_from, quote, date FROM tell " \ - "WHERE name LIKE ? and chan = ?" - tells = cursor.execute(command, (input.nick, input.chan)).fetchall() - - if(len(tells) > 0): - for tell in tells: - reltime = timesince.timesince(datetime.fromtimestamp(tell[3])) - input.msg(input.nick, '%(teller)s said %(time)s ago: %(quote)s' % - {'teller': tell[1], 'quote': tell[2], 'time': reltime}) - - command = "delete from tell where id = ?" - cursor.execute(command, (tell[0], )) - - conn.commit() - else: - input.pm("You have no pending tells.") - - conn.close() - - -@hook.command -def tell(bot, input): - ".tell -- relay to when is around" - - if len(input.msg) < 6: - return tell.__doc__ - - query = input.msg[6:].strip().partition(" ") - - if query[0] == input.nick: - return "No." - - - if query[2] != "": - dbpath = os.path.join(bot.persist_dir, dbname) - conn = dbconnect(dbpath) - - command = "select count(*) from tell_probation where name=? and chan=?" - if conn.execute(command, (input.nick, input.chan)).fetchone()[0] > 0: - return "No." - - command = "select count(*) from tell where name=? and user_from=?" - if conn.execute(command, (query[0], input.nick)).fetchone()[0] >= 3: - return "You've told that person too many things." - - cursor = conn.cursor() - command = "insert into tell(name, user_from, quote, chan, date) " \ - "values(?,?,?,?,?)" - cursor.execute(command, (query[0], input.nick, query[2], input.chan, - datetime.now())) - - conn.commit() - conn.close() - return "I'll pass that along." - - else: - return tell.__doc__ - - -def dbconnect(db): - "check to see that our db has the tell table and return a connection." - conn = sqlite3.connect(db) - - conn.execute("CREATE TABLE IF NOT EXISTS tell(id integer primary key " - "autoincrement, name text not null, user_from text not null," - "quote text not null, chan text not null, " - "date datetime not null);") - - conn.execute("CREATE TABLE IF NOT EXISTS " - "tell_probation(name text, chan text," - "primary key(name, chan));") - - conn.commit() - - return conn diff --git a/plugins_available/tinyurl.py b/plugins_available/tinyurl.py deleted file mode 100644 index 4dd1277..0000000 --- a/plugins_available/tinyurl.py +++ /dev/null @@ -1,18 +0,0 @@ -import re -import urllib2 - -from util import hook - - -tinyurl_re = re.compile(r'http://(?:www\.)?tinyurl.com/([A-Za-z0-9\-]+)', - flags=re.IGNORECASE) - - -@hook.command(hook=r'(.*)', prefix=False) -def tinyurl(inp): - tumatch = tinyurl_re.search(inp) - if tumatch: - try: - return urllib2.urlopen(tumatch.group()).url.strip() - except urllib2.URLError: - pass diff --git a/plugins_available/twitter.py b/plugins_available/twitter.py deleted file mode 100644 index 1e605c7..0000000 --- a/plugins_available/twitter.py +++ /dev/null @@ -1,137 +0,0 @@ -""" -twitter.py: written by Scaevolus 2009 -retrieves most recent tweets -""" - -import re -import random -import urllib2 -from lxml import etree -from time import strptime, strftime - -from util import hook - - -def unescape_xml(string): - # unescape the 5 chars that might be escaped in xml - - # gratuitously functional - # return reduce(lambda x, y: x.replace(*y), (string, - # zip('> < ' "e; &'.split(), '> < \' " &'.split())) - - # boring, normal - return string.replace('>', '>').replace('<', '<').replace(''', - "'").replace('"e;', '"').replace('&', '&') - -history = [] -history_max_size = 250 - -@hook.command -def twitter(inp): - ".twitter / //#/@ -- gets last/th tweet from"\ - "/gets tweet /gets random tweet with #/gets replied tweet from @" - - inp = inp.strip() - if not inp: - return twitter.__doc__ - - def add_reply(reply_name, reply_id): - if len(history) == history_max_size: - history.pop() - history.insert(0, (reply_name, reply_id)) - - def find_reply(reply_name): - for name, id in history: - if name == reply_name: - return id - - if inp[0] == '@': - reply_id = find_reply(inp[1:]) - if reply_id == None: - return 'error: no replies to %s found' % inp - inp = reply_id - - url = 'http://twitter.com' - getting_nth = False - getting_id = False - searching_hashtag = False - - time = 'status/created_at' - text = 'status/text' - reply_name = 'status/in_reply_to_screen_name' - reply_id = 'status/in_reply_to_status_id' - - if re.match(r'^\d+$', inp): - getting_id = True - url += '/statuses/show/%s.xml' % inp - screen_name = 'user/screen_name' - time = 'created_at' - text = 'text' - reply_name = 'in_reply_to_screen_name' - reply_id = 'in_reply_to_status_id' - elif re.match(r'^\w{1,15}$', inp): - url += '/users/show/%s.xml' % inp - screen_name = 'screen_name' - elif re.match(r'^\w{1,15}\s+\d+$', inp): - getting_nth = True - name, num = inp.split() - if int(num) > 3200: - return 'error: only supports up to the 3200th tweet' - url += '/statuses/user_timeline/%s.xml?count=1&page=%s' % (name, num) - screen_name = 'status/user/screen_name' - elif re.match(r'^#\w+$', inp): - url = 'http://search.twitter.com/search.atom?q=%23' + inp[1:] - searching_hashtag = True - else: - return 'error: invalid request' - - try: - xml = urllib2.urlopen(url).read() - except urllib2.HTTPError, e: - errors = {400 : 'bad request (ratelimited?)', - 401: 'tweet is private', - 404: 'invalid user/id', - 500: 'twitter is broken', - 502: 'twitter is down ("getting upgraded")', - 503: 'twitter is overloaded (lol, RoR)'} - if e.code == 404: - return 'error: invalid ' + ['username', 'tweet id'][getting_id] - if e.code in errors: - return 'error: ' + errors[e.code] - return 'error: unknown' - except urllib2.URLerror, e: - return 'error: timeout' - - tweet = etree.fromstring(xml) - - if searching_hashtag: - ns = '{http://www.w3.org/2005/Atom}' - tweets = tweet.findall(ns + 'entry/' + ns + 'id') - if not tweets: - return 'error: hashtag not found' - id = random.choice(tweets).text - id = id[id.rfind(':') + 1:] - print id - return twitter(id) - - if getting_nth: - if tweet.find('status') is None: - return 'error: user does not have that many tweets' - - time = tweet.find(time) - if time is None: - return 'error: user has no tweets' - - reply_name = tweet.find(reply_name).text - reply_id = tweet.find(reply_id).text - if reply_name is not None and reply_id is not None: - add_reply(reply_name, reply_id) - - time = strftime('%Y-%m-%d %H:%M:%S', - strptime(time.text, - '%a %b %d %H:%M:%S +0000 %Y')) - text = unescape_xml(tweet.find(text).text.replace('\n', '')) - screen_name = tweet.find(screen_name).text - - return "%s %s: %s" % (time, screen_name, text) - diff --git a/plugins_available/urbandictionary.py b/plugins_available/urbandictionary.py deleted file mode 100644 index 2327df6..0000000 --- a/plugins_available/urbandictionary.py +++ /dev/null @@ -1,29 +0,0 @@ -from lxml import html -import urllib - -from util import hook - - -@hook.command('u') -@hook.command -def urban(inp): - '''.u/.urban -- looks up on urbandictionary.com''' - if not inp.strip(): - return urban.__doc__ - - url = 'http://www.urbandictionary.com/define.php?term=' + \ - urllib.quote(inp.strip(), safe='') - page = html.parse(url) - words = page.xpath("//td[@class='word']") - defs = page.xpath("//div[@class='definition']") - - if not defs: - return 'no definitions found' - - out = words[0].text_content().strip() + ': ' + ' '.join( - defs[0].text_content().split()) - - if len(out) > 400: - out = out[:out.rfind(' ', 0, 400)] + '...' - - return out diff --git a/plugins_available/util/__init__.py b/plugins_available/util/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/plugins_available/util/hook.py b/plugins_available/util/hook.py deleted file mode 100644 index f6e257a..0000000 --- a/plugins_available/util/hook.py +++ /dev/null @@ -1,94 +0,0 @@ -import Queue -import thread -import traceback - -def _isfunc(x): - if type(x) == type(_isfunc): - return True - return False - - -def _hook_add(func, add): - if not hasattr(func, '_skybot_hook'): - func._skybot_hook = [] - func._skybot_hook.append(add) - - -def _make_sig(f): - return f.func_code.co_filename, f.func_name, f.func_code.co_firstlineno - - -def sieve(func): - if func.func_code.co_argcount != 4: - raise ValueError( - 'sieves must take 4 arguments: (bot, input, func, args)') - _hook_add(func, ['sieve', (_make_sig(func), func)]) - return func - - -def command(func=None, hook=None, **kwargs): - args = {} - - def command_wrapper(func): - if func.func_code.co_argcount not in (1, 2): - raise ValueError( - 'commands must take 1 or 2 arguments: (inp) or (bot, input)') - args.setdefault('name', func.func_name) - args.setdefault('hook', args['name'] + r'(?:\s+|$)(.*)') - _hook_add(func, ['command', (_make_sig(func), func, args)]) - return func - - if hook is not None or kwargs or not _isfunc(func): - if func is not None: - args['name'] = func - if hook is not None: - args['hook'] = hook - args.update(kwargs) - return command_wrapper - else: - return command_wrapper(func) - - -def event(arg=None, **kwargs): - args = kwargs - - def event_wrapper(func): - if func.func_code.co_argcount != 2: - raise ValueError('events must take 2 arguments: (bot, input)') - args['name'] = func.func_name - args['prefix'] = False - args.setdefault('events', '*') - _hook_add(func, ['event', (_make_sig(func), func, args)]) - return func - - if _isfunc(arg): - return event_wrapper(arg, kwargs) - else: - if arg is not None: - args['events'] = arg.split() - return event_wrapper - - -def tee(func, **kwargs): - "passes _all_ input lines to function, in order (skips sieves)" - - if func.func_code.co_argcount != 2: - raise ValueError('tees must take 2 arguments: (bot, input)') - - _hook_add(func, ['tee', (_make_sig(func), func, kwargs)]) - func._iqueue = Queue.Queue() - - def trampoline(func): - input = None - while True: - input = func._iqueue.get() - if input == StopIteration: - return - try: - func(*input) - except Exception: - traceback.print_exc(Exception) - - thread.start_new_thread(trampoline, (func,)) - - return func diff --git a/plugins_available/util/timesince.py b/plugins_available/util/timesince.py deleted file mode 100644 index 03e8802..0000000 --- a/plugins_available/util/timesince.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) Django Software Foundation and individual contributors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of Django nor the names of its contributors may be used -# to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import datetime -import time - -def timesince(d, now=None): - """ - Takes two datetime objects and returns the time between d and now - as a nicely formatted string, e.g. "10 minutes". If d occurs after now, - then "0 minutes" is returned. - - Units used are years, months, weeks, days, hours, and minutes. - Seconds and microseconds are ignored. Up to two adjacent units will be - displayed. For example, "2 weeks, 3 days" and "1 year, 3 months" are - possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not. - - Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since - """ - chunks = ( - (60 * 60 * 24 * 365, ('year', 'years')), - (60 * 60 * 24 * 30, ('month', 'months')), - (60 * 60 * 24 * 7, ('week', 'weeks')), - (60 * 60 * 24, ('day', 'days')), - (60 * 60, ('hour', 'hours')), - (60, ('minute', 'minutes')) - ) - # Convert datetime.date to datetime.datetime for comparison. - if not isinstance(d, datetime.datetime): - d = datetime.datetime(d.year, d.month, d.day) - if now and not isinstance(now, datetime.datetime): - now = datetime.datetime(now.year, now.month, now.day) - - if not now: - now = datetime.datetime.now() - - # ignore microsecond part of 'd' since we removed it from 'now' - delta = now - (d - datetime.timedelta(0, 0, d.microsecond)) - since = delta.days * 24 * 60 * 60 + delta.seconds - if since <= 0: - # d is in the future compared to now, stop processing. - return u'0 ' + 'minutes' - for i, (seconds, name) in enumerate(chunks): - count = since // seconds - if count != 0: - break - - if count == 1: - s = '%(number)d %(type)s' % {'number': count, 'type': name[0]} - else: - s = '%(number)d %(type)s' % {'number': count, 'type': name[1]} - - if i + 1 < len(chunks): - # Now get the second item - seconds2, name2 = chunks[i + 1] - count2 = (since - (seconds * count)) // seconds2 - if count2 != 0: - if count2 == 1: - s += ', %(number)d %(type)s' % {'number': count2, 'type': name2[0]} - else: - s += ', %(number)d %(type)s' % {'number': count2, 'type': name2[1]} - return s - -def timeuntil(d, now=None): - """ - Like timesince, but returns a string measuring the time until - the given time. - """ - if not now: - now = datetime.datetime.now() - return timesince(now, d) diff --git a/plugins_available/util/yaml/LICENSE b/plugins_available/util/yaml/LICENSE deleted file mode 100644 index 050ced2..0000000 --- a/plugins_available/util/yaml/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2006 Kirill Simonov - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/plugins_available/util/yaml/PKG-INFO b/plugins_available/util/yaml/PKG-INFO deleted file mode 100644 index eb63484..0000000 --- a/plugins_available/util/yaml/PKG-INFO +++ /dev/null @@ -1,36 +0,0 @@ -Metadata-Version: 1.0 -Name: PyYAML -Version: 3.09 -Summary: YAML parser and emitter for Python -Home-page: http://pyyaml.org/wiki/PyYAML -Author: Kirill Simonov -Author-email: xi@resolvent.net -License: MIT -Download-URL: http://pyyaml.org/download/pyyaml/PyYAML-3.09.tar.gz -Description: YAML is a data serialization format designed for human readability - and interaction with scripting languages. PyYAML is a YAML parser - and emitter for Python. - - PyYAML features a complete YAML 1.1 parser, Unicode support, pickle - support, capable extension API, and sensible error messages. PyYAML - supports standard YAML tags and provides Python-specific tags that - allow to represent an arbitrary Python object. - - PyYAML is applicable for a broad range of tasks from complex - configuration files to object serialization and persistance. -Platform: Any -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.3 -Classifier: Programming Language :: Python :: 2.4 -Classifier: Programming Language :: Python :: 2.5 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.0 -Classifier: Programming Language :: Python :: 3.1 -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Text Processing :: Markup diff --git a/plugins_available/util/yaml/README b/plugins_available/util/yaml/README deleted file mode 100644 index c1edf13..0000000 --- a/plugins_available/util/yaml/README +++ /dev/null @@ -1,35 +0,0 @@ -PyYAML - The next generation YAML parser and emitter for Python. - -To install, type 'python setup.py install'. - -By default, the setup.py script checks whether LibYAML is installed -and if so, builds and installs LibYAML bindings. To skip the check -and force installation of LibYAML bindings, use the option '--with-libyaml': -'python setup.py --with-libyaml install'. To disable the check and -skip building and installing LibYAML bindings, use '--without-libyaml': -'python setup.py --without-libyaml install'. - -When LibYAML bindings are installed, you may use fast LibYAML-based -parser and emitter as follows: - - >>> yaml.load(stream, Loader=yaml.CLoader) - >>> yaml.dump(data, Dumper=yaml.CDumper) - -PyYAML includes a comprehensive test suite. To run the tests, -type 'python setup.py test'. - -For more information, check the PyYAML homepage: -'http://pyyaml.org/wiki/PyYAML'. - -For PyYAML tutorial and reference, see: -'http://pyyaml.org/wiki/PyYAMLDocumentation'. - -Post your questions and opinions to the YAML-Core mailing list: -'http://lists.sourceforge.net/lists/listinfo/yaml-core'. - -Submit bug reports and feature requests to the PyYAML bug tracker: -'http://pyyaml.org/newticket?component=pyyaml'. - -PyYAML is written by Kirill Simonov . It is released -under the MIT license. See the file LICENSE for more details. - diff --git a/plugins_available/util/yaml/__init__.py b/plugins_available/util/yaml/__init__.py deleted file mode 100644 index c0fd1f3..0000000 --- a/plugins_available/util/yaml/__init__.py +++ /dev/null @@ -1,288 +0,0 @@ - -from error import * - -from tokens import * -from events import * -from nodes import * - -from loader import * -from dumper import * - -__version__ = '3.09' - -try: - from cyaml import * - __with_libyaml__ = True -except ImportError: - __with_libyaml__ = False - -def scan(stream, Loader=Loader): - """ - Scan a YAML stream and produce scanning tokens. - """ - loader = Loader(stream) - while loader.check_token(): - yield loader.get_token() - -def parse(stream, Loader=Loader): - """ - Parse a YAML stream and produce parsing events. - """ - loader = Loader(stream) - while loader.check_event(): - yield loader.get_event() - -def compose(stream, Loader=Loader): - """ - Parse the first YAML document in a stream - and produce the corresponding representation tree. - """ - loader = Loader(stream) - return loader.get_single_node() - -def compose_all(stream, Loader=Loader): - """ - Parse all YAML documents in a stream - and produce corresponding representation trees. - """ - loader = Loader(stream) - while loader.check_node(): - yield loader.get_node() - -def load(stream, Loader=Loader): - """ - Parse the first YAML document in a stream - and produce the corresponding Python object. - """ - loader = Loader(stream) - return loader.get_single_data() - -def load_all(stream, Loader=Loader): - """ - Parse all YAML documents in a stream - and produce corresponding Python objects. - """ - loader = Loader(stream) - while loader.check_data(): - yield loader.get_data() - -def safe_load(stream): - """ - Parse the first YAML document in a stream - and produce the corresponding Python object. - Resolve only basic YAML tags. - """ - return load(stream, SafeLoader) - -def safe_load_all(stream): - """ - Parse all YAML documents in a stream - and produce corresponding Python objects. - Resolve only basic YAML tags. - """ - return load_all(stream, SafeLoader) - -def emit(events, stream=None, Dumper=Dumper, - canonical=None, indent=None, width=None, - allow_unicode=None, line_break=None): - """ - Emit YAML parsing events into a stream. - If stream is None, return the produced string instead. - """ - getvalue = None - if stream is None: - from StringIO import StringIO - stream = StringIO() - getvalue = stream.getvalue - dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, - allow_unicode=allow_unicode, line_break=line_break) - for event in events: - dumper.emit(event) - if getvalue: - return getvalue() - -def serialize_all(nodes, stream=None, Dumper=Dumper, - canonical=None, indent=None, width=None, - allow_unicode=None, line_break=None, - encoding='utf-8', explicit_start=None, explicit_end=None, - version=None, tags=None): - """ - Serialize a sequence of representation trees into a YAML stream. - If stream is None, return the produced string instead. - """ - getvalue = None - if stream is None: - if encoding is None: - from StringIO import StringIO - else: - from cStringIO import StringIO - stream = StringIO() - getvalue = stream.getvalue - dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, - allow_unicode=allow_unicode, line_break=line_break, - encoding=encoding, version=version, tags=tags, - explicit_start=explicit_start, explicit_end=explicit_end) - dumper.open() - for node in nodes: - dumper.serialize(node) - dumper.close() - if getvalue: - return getvalue() - -def serialize(node, stream=None, Dumper=Dumper, **kwds): - """ - Serialize a representation tree into a YAML stream. - If stream is None, return the produced string instead. - """ - return serialize_all([node], stream, Dumper=Dumper, **kwds) - -def dump_all(documents, stream=None, Dumper=Dumper, - default_style=None, default_flow_style=None, - canonical=None, indent=None, width=None, - allow_unicode=None, line_break=None, - encoding='utf-8', explicit_start=None, explicit_end=None, - version=None, tags=None): - """ - Serialize a sequence of Python objects into a YAML stream. - If stream is None, return the produced string instead. - """ - getvalue = None - if stream is None: - if encoding is None: - from StringIO import StringIO - else: - from cStringIO import StringIO - stream = StringIO() - getvalue = stream.getvalue - dumper = Dumper(stream, default_style=default_style, - default_flow_style=default_flow_style, - canonical=canonical, indent=indent, width=width, - allow_unicode=allow_unicode, line_break=line_break, - encoding=encoding, version=version, tags=tags, - explicit_start=explicit_start, explicit_end=explicit_end) - dumper.open() - for data in documents: - dumper.represent(data) - dumper.close() - if getvalue: - return getvalue() - -def dump(data, stream=None, Dumper=Dumper, **kwds): - """ - Serialize a Python object into a YAML stream. - If stream is None, return the produced string instead. - """ - return dump_all([data], stream, Dumper=Dumper, **kwds) - -def safe_dump_all(documents, stream=None, **kwds): - """ - Serialize a sequence of Python objects into a YAML stream. - Produce only basic YAML tags. - If stream is None, return the produced string instead. - """ - return dump_all(documents, stream, Dumper=SafeDumper, **kwds) - -def safe_dump(data, stream=None, **kwds): - """ - Serialize a Python object into a YAML stream. - Produce only basic YAML tags. - If stream is None, return the produced string instead. - """ - return dump_all([data], stream, Dumper=SafeDumper, **kwds) - -def add_implicit_resolver(tag, regexp, first=None, - Loader=Loader, Dumper=Dumper): - """ - Add an implicit scalar detector. - If an implicit scalar value matches the given regexp, - the corresponding tag is assigned to the scalar. - first is a sequence of possible initial characters or None. - """ - Loader.add_implicit_resolver(tag, regexp, first) - Dumper.add_implicit_resolver(tag, regexp, first) - -def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper): - """ - Add a path based resolver for the given tag. - A path is a list of keys that forms a path - to a node in the representation tree. - Keys can be string values, integers, or None. - """ - Loader.add_path_resolver(tag, path, kind) - Dumper.add_path_resolver(tag, path, kind) - -def add_constructor(tag, constructor, Loader=Loader): - """ - Add a constructor for the given tag. - Constructor is a function that accepts a Loader instance - and a node object and produces the corresponding Python object. - """ - Loader.add_constructor(tag, constructor) - -def add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader): - """ - Add a multi-constructor for the given tag prefix. - Multi-constructor is called for a node if its tag starts with tag_prefix. - Multi-constructor accepts a Loader instance, a tag suffix, - and a node object and produces the corresponding Python object. - """ - Loader.add_multi_constructor(tag_prefix, multi_constructor) - -def add_representer(data_type, representer, Dumper=Dumper): - """ - Add a representer for the given type. - Representer is a function accepting a Dumper instance - and an instance of the given data type - and producing the corresponding representation node. - """ - Dumper.add_representer(data_type, representer) - -def add_multi_representer(data_type, multi_representer, Dumper=Dumper): - """ - Add a representer for the given type. - Multi-representer is a function accepting a Dumper instance - and an instance of the given data type or subtype - and producing the corresponding representation node. - """ - Dumper.add_multi_representer(data_type, multi_representer) - -class YAMLObjectMetaclass(type): - """ - The metaclass for YAMLObject. - """ - def __init__(cls, name, bases, kwds): - super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds) - if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None: - cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml) - cls.yaml_dumper.add_representer(cls, cls.to_yaml) - -class YAMLObject(object): - """ - An object that can dump itself to a YAML stream - and load itself from a YAML stream. - """ - - __metaclass__ = YAMLObjectMetaclass - __slots__ = () # no direct instantiation, so allow immutable subclasses - - yaml_loader = Loader - yaml_dumper = Dumper - - yaml_tag = None - yaml_flow_style = None - - def from_yaml(cls, loader, node): - """ - Convert a representation node to a Python object. - """ - return loader.construct_yaml_object(node, cls) - from_yaml = classmethod(from_yaml) - - def to_yaml(cls, dumper, data): - """ - Convert a Python object to a representation node. - """ - return dumper.represent_yaml_object(cls.yaml_tag, data, cls, - flow_style=cls.yaml_flow_style) - to_yaml = classmethod(to_yaml) - diff --git a/plugins_available/util/yaml/composer.py b/plugins_available/util/yaml/composer.py deleted file mode 100644 index 06e5ac7..0000000 --- a/plugins_available/util/yaml/composer.py +++ /dev/null @@ -1,139 +0,0 @@ - -__all__ = ['Composer', 'ComposerError'] - -from error import MarkedYAMLError -from events import * -from nodes import * - -class ComposerError(MarkedYAMLError): - pass - -class Composer(object): - - def __init__(self): - self.anchors = {} - - def check_node(self): - # Drop the STREAM-START event. - if self.check_event(StreamStartEvent): - self.get_event() - - # If there are more documents available? - return not self.check_event(StreamEndEvent) - - def get_node(self): - # Get the root node of the next document. - if not self.check_event(StreamEndEvent): - return self.compose_document() - - def get_single_node(self): - # Drop the STREAM-START event. - self.get_event() - - # Compose a document if the stream is not empty. - document = None - if not self.check_event(StreamEndEvent): - document = self.compose_document() - - # Ensure that the stream contains no more documents. - if not self.check_event(StreamEndEvent): - event = self.get_event() - raise ComposerError("expected a single document in the stream", - document.start_mark, "but found another document", - event.start_mark) - - # Drop the STREAM-END event. - self.get_event() - - return document - - def compose_document(self): - # Drop the DOCUMENT-START event. - self.get_event() - - # Compose the root node. - node = self.compose_node(None, None) - - # Drop the DOCUMENT-END event. - self.get_event() - - self.anchors = {} - return node - - def compose_node(self, parent, index): - if self.check_event(AliasEvent): - event = self.get_event() - anchor = event.anchor - if anchor not in self.anchors: - raise ComposerError(None, None, "found undefined alias %r" - % anchor.encode('utf-8'), event.start_mark) - return self.anchors[anchor] - event = self.peek_event() - anchor = event.anchor - if anchor is not None: - if anchor in self.anchors: - raise ComposerError("found duplicate anchor %r; first occurence" - % anchor.encode('utf-8'), self.anchors[anchor].start_mark, - "second occurence", event.start_mark) - self.descend_resolver(parent, index) - if self.check_event(ScalarEvent): - node = self.compose_scalar_node(anchor) - elif self.check_event(SequenceStartEvent): - node = self.compose_sequence_node(anchor) - elif self.check_event(MappingStartEvent): - node = self.compose_mapping_node(anchor) - self.ascend_resolver() - return node - - def compose_scalar_node(self, anchor): - event = self.get_event() - tag = event.tag - if tag is None or tag == u'!': - tag = self.resolve(ScalarNode, event.value, event.implicit) - node = ScalarNode(tag, event.value, - event.start_mark, event.end_mark, style=event.style) - if anchor is not None: - self.anchors[anchor] = node - return node - - def compose_sequence_node(self, anchor): - start_event = self.get_event() - tag = start_event.tag - if tag is None or tag == u'!': - tag = self.resolve(SequenceNode, None, start_event.implicit) - node = SequenceNode(tag, [], - start_event.start_mark, None, - flow_style=start_event.flow_style) - if anchor is not None: - self.anchors[anchor] = node - index = 0 - while not self.check_event(SequenceEndEvent): - node.value.append(self.compose_node(node, index)) - index += 1 - end_event = self.get_event() - node.end_mark = end_event.end_mark - return node - - def compose_mapping_node(self, anchor): - start_event = self.get_event() - tag = start_event.tag - if tag is None or tag == u'!': - tag = self.resolve(MappingNode, None, start_event.implicit) - node = MappingNode(tag, [], - start_event.start_mark, None, - flow_style=start_event.flow_style) - if anchor is not None: - self.anchors[anchor] = node - while not self.check_event(MappingEndEvent): - #key_event = self.peek_event() - item_key = self.compose_node(node, None) - #if item_key in node.value: - # raise ComposerError("while composing a mapping", start_event.start_mark, - # "found duplicate key", key_event.start_mark) - item_value = self.compose_node(node, item_key) - #node.value[item_key] = item_value - node.value.append((item_key, item_value)) - end_event = self.get_event() - node.end_mark = end_event.end_mark - return node - diff --git a/plugins_available/util/yaml/constructor.py b/plugins_available/util/yaml/constructor.py deleted file mode 100644 index 420c434..0000000 --- a/plugins_available/util/yaml/constructor.py +++ /dev/null @@ -1,684 +0,0 @@ - -__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor', - 'ConstructorError'] - -from error import * -from nodes import * - -import datetime - -try: - set -except NameError: - from sets import Set as set - -import binascii, re, sys, types - -class ConstructorError(MarkedYAMLError): - pass - -class BaseConstructor(object): - - yaml_constructors = {} - yaml_multi_constructors = {} - - def __init__(self): - self.constructed_objects = {} - self.recursive_objects = {} - self.state_generators = [] - self.deep_construct = False - - def check_data(self): - # If there are more documents available? - return self.check_node() - - def get_data(self): - # Construct and return the next document. - if self.check_node(): - return self.construct_document(self.get_node()) - - def get_single_data(self): - # Ensure that the stream contains a single document and construct it. - node = self.get_single_node() - if node is not None: - return self.construct_document(node) - return None - - def construct_document(self, node): - data = self.construct_object(node) - while self.state_generators: - state_generators = self.state_generators - self.state_generators = [] - for generator in state_generators: - for dummy in generator: - pass - self.constructed_objects = {} - self.recursive_objects = {} - self.deep_construct = False - return data - - def construct_object(self, node, deep=False): - if deep: - old_deep = self.deep_construct - self.deep_construct = True - if node in self.constructed_objects: - return self.constructed_objects[node] - if node in self.recursive_objects: - raise ConstructorError(None, None, - "found unconstructable recursive node", node.start_mark) - self.recursive_objects[node] = None - constructor = None - tag_suffix = None - if node.tag in self.yaml_constructors: - constructor = self.yaml_constructors[node.tag] - else: - for tag_prefix in self.yaml_multi_constructors: - if node.tag.startswith(tag_prefix): - tag_suffix = node.tag[len(tag_prefix):] - constructor = self.yaml_multi_constructors[tag_prefix] - break - else: - if None in self.yaml_multi_constructors: - tag_suffix = node.tag - constructor = self.yaml_multi_constructors[None] - elif None in self.yaml_constructors: - constructor = self.yaml_constructors[None] - elif isinstance(node, ScalarNode): - constructor = self.__class__.construct_scalar - elif isinstance(node, SequenceNode): - constructor = self.__class__.construct_sequence - elif isinstance(node, MappingNode): - constructor = self.__class__.construct_mapping - if tag_suffix is None: - data = constructor(self, node) - else: - data = constructor(self, tag_suffix, node) - if isinstance(data, types.GeneratorType): - generator = data - data = generator.next() - if self.deep_construct: - for dummy in generator: - pass - else: - self.state_generators.append(generator) - self.constructed_objects[node] = data - del self.recursive_objects[node] - if deep: - self.deep_construct = old_deep - return data - - def construct_scalar(self, node): - if not isinstance(node, ScalarNode): - raise ConstructorError(None, None, - "expected a scalar node, but found %s" % node.id, - node.start_mark) - return node.value - - def construct_sequence(self, node, deep=False): - if not isinstance(node, SequenceNode): - raise ConstructorError(None, None, - "expected a sequence node, but found %s" % node.id, - node.start_mark) - return [self.construct_object(child, deep=deep) - for child in node.value] - - def construct_mapping(self, node, deep=False): - if not isinstance(node, MappingNode): - raise ConstructorError(None, None, - "expected a mapping node, but found %s" % node.id, - node.start_mark) - mapping = {} - for key_node, value_node in node.value: - key = self.construct_object(key_node, deep=deep) - try: - hash(key) - except TypeError, exc: - raise ConstructorError("while constructing a mapping", node.start_mark, - "found unacceptable key (%s)" % exc, key_node.start_mark) - value = self.construct_object(value_node, deep=deep) - mapping[key] = value - return mapping - - def construct_pairs(self, node, deep=False): - if not isinstance(node, MappingNode): - raise ConstructorError(None, None, - "expected a mapping node, but found %s" % node.id, - node.start_mark) - pairs = [] - for key_node, value_node in node.value: - key = self.construct_object(key_node, deep=deep) - value = self.construct_object(value_node, deep=deep) - pairs.append((key, value)) - return pairs - - def add_constructor(cls, tag, constructor): - if not 'yaml_constructors' in cls.__dict__: - cls.yaml_constructors = cls.yaml_constructors.copy() - cls.yaml_constructors[tag] = constructor - add_constructor = classmethod(add_constructor) - - def add_multi_constructor(cls, tag_prefix, multi_constructor): - if not 'yaml_multi_constructors' in cls.__dict__: - cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy() - cls.yaml_multi_constructors[tag_prefix] = multi_constructor - add_multi_constructor = classmethod(add_multi_constructor) - -class SafeConstructor(BaseConstructor): - - def construct_scalar(self, node): - if isinstance(node, MappingNode): - for key_node, value_node in node.value: - if key_node.tag == u'tag:yaml.org,2002:value': - return self.construct_scalar(value_node) - return BaseConstructor.construct_scalar(self, node) - - def flatten_mapping(self, node): - merge = [] - index = 0 - while index < len(node.value): - key_node, value_node = node.value[index] - if key_node.tag == u'tag:yaml.org,2002:merge': - del node.value[index] - if isinstance(value_node, MappingNode): - self.flatten_mapping(value_node) - merge.extend(value_node.value) - elif isinstance(value_node, SequenceNode): - submerge = [] - for subnode in value_node.value: - if not isinstance(subnode, MappingNode): - raise ConstructorError("while constructing a mapping", - node.start_mark, - "expected a mapping for merging, but found %s" - % subnode.id, subnode.start_mark) - self.flatten_mapping(subnode) - submerge.append(subnode.value) - submerge.reverse() - for value in submerge: - merge.extend(value) - else: - raise ConstructorError("while constructing a mapping", node.start_mark, - "expected a mapping or list of mappings for merging, but found %s" - % value_node.id, value_node.start_mark) - elif key_node.tag == u'tag:yaml.org,2002:value': - key_node.tag = u'tag:yaml.org,2002:str' - index += 1 - else: - index += 1 - if merge: - node.value = merge + node.value - - def construct_mapping(self, node, deep=False): - if isinstance(node, MappingNode): - self.flatten_mapping(node) - return BaseConstructor.construct_mapping(self, node, deep=deep) - - def construct_yaml_null(self, node): - self.construct_scalar(node) - return None - - bool_values = { - u'yes': True, - u'no': False, - u'true': True, - u'false': False, - u'on': True, - u'off': False, - } - - def construct_yaml_bool(self, node): - value = self.construct_scalar(node) - return self.bool_values[value.lower()] - - def construct_yaml_int(self, node): - value = str(self.construct_scalar(node)) - value = value.replace('_', '') - sign = +1 - if value[0] == '-': - sign = -1 - if value[0] in '+-': - value = value[1:] - if value == '0': - return 0 - elif value.startswith('0b'): - return sign*int(value[2:], 2) - elif value.startswith('0x'): - return sign*int(value[2:], 16) - elif value[0] == '0': - return sign*int(value, 8) - elif ':' in value: - digits = [int(part) for part in value.split(':')] - digits.reverse() - base = 1 - value = 0 - for digit in digits: - value += digit*base - base *= 60 - return sign*value - else: - return sign*int(value) - - inf_value = 1e300 - while inf_value != inf_value*inf_value: - inf_value *= inf_value - nan_value = -inf_value/inf_value # Trying to make a quiet NaN (like C99). - - def construct_yaml_float(self, node): - value = str(self.construct_scalar(node)) - value = value.replace('_', '').lower() - sign = +1 - if value[0] == '-': - sign = -1 - if value[0] in '+-': - value = value[1:] - if value == '.inf': - return sign*self.inf_value - elif value == '.nan': - return self.nan_value - elif ':' in value: - digits = [float(part) for part in value.split(':')] - digits.reverse() - base = 1 - value = 0.0 - for digit in digits: - value += digit*base - base *= 60 - return sign*value - else: - return sign*float(value) - - def construct_yaml_binary(self, node): - value = self.construct_scalar(node) - try: - return str(value).decode('base64') - except (binascii.Error, UnicodeEncodeError), exc: - raise ConstructorError(None, None, - "failed to decode base64 data: %s" % exc, node.start_mark) - - timestamp_regexp = re.compile( - ur'''^(?P[0-9][0-9][0-9][0-9]) - -(?P[0-9][0-9]?) - -(?P[0-9][0-9]?) - (?:(?:[Tt]|[ \t]+) - (?P[0-9][0-9]?) - :(?P[0-9][0-9]) - :(?P[0-9][0-9]) - (?:\.(?P[0-9]*))? - (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) - (?::(?P[0-9][0-9]))?))?)?$''', re.X) - - def construct_yaml_timestamp(self, node): - value = self.construct_scalar(node) - match = self.timestamp_regexp.match(node.value) - values = match.groupdict() - year = int(values['year']) - month = int(values['month']) - day = int(values['day']) - if not values['hour']: - return datetime.date(year, month, day) - hour = int(values['hour']) - minute = int(values['minute']) - second = int(values['second']) - fraction = 0 - if values['fraction']: - fraction = values['fraction'][:6] - while len(fraction) < 6: - fraction += '0' - fraction = int(fraction) - delta = None - if values['tz_sign']: - tz_hour = int(values['tz_hour']) - tz_minute = int(values['tz_minute'] or 0) - delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute) - if values['tz_sign'] == '-': - delta = -delta - data = datetime.datetime(year, month, day, hour, minute, second, fraction) - if delta: - data -= delta - return data - - def construct_yaml_omap(self, node): - # Note: we do not check for duplicate keys, because it's too - # CPU-expensive. - omap = [] - yield omap - if not isinstance(node, SequenceNode): - raise ConstructorError("while constructing an ordered map", node.start_mark, - "expected a sequence, but found %s" % node.id, node.start_mark) - for subnode in node.value: - if not isinstance(subnode, MappingNode): - raise ConstructorError("while constructing an ordered map", node.start_mark, - "expected a mapping of length 1, but found %s" % subnode.id, - subnode.start_mark) - if len(subnode.value) != 1: - raise ConstructorError("while constructing an ordered map", node.start_mark, - "expected a single mapping item, but found %d items" % len(subnode.value), - subnode.start_mark) - key_node, value_node = subnode.value[0] - key = self.construct_object(key_node) - value = self.construct_object(value_node) - omap.append((key, value)) - - def construct_yaml_pairs(self, node): - # Note: the same code as `construct_yaml_omap`. - pairs = [] - yield pairs - if not isinstance(node, SequenceNode): - raise ConstructorError("while constructing pairs", node.start_mark, - "expected a sequence, but found %s" % node.id, node.start_mark) - for subnode in node.value: - if not isinstance(subnode, MappingNode): - raise ConstructorError("while constructing pairs", node.start_mark, - "expected a mapping of length 1, but found %s" % subnode.id, - subnode.start_mark) - if len(subnode.value) != 1: - raise ConstructorError("while constructing pairs", node.start_mark, - "expected a single mapping item, but found %d items" % len(subnode.value), - subnode.start_mark) - key_node, value_node = subnode.value[0] - key = self.construct_object(key_node) - value = self.construct_object(value_node) - pairs.append((key, value)) - - def construct_yaml_set(self, node): - data = set() - yield data - value = self.construct_mapping(node) - data.update(value) - - def construct_yaml_str(self, node): - value = self.construct_scalar(node) - try: - return value.encode('ascii') - except UnicodeEncodeError: - return value - - def construct_yaml_seq(self, node): - data = [] - yield data - data.extend(self.construct_sequence(node)) - - def construct_yaml_map(self, node): - data = {} - yield data - value = self.construct_mapping(node) - data.update(value) - - def construct_yaml_object(self, node, cls): - data = cls.__new__(cls) - yield data - if hasattr(data, '__setstate__'): - state = self.construct_mapping(node, deep=True) - data.__setstate__(state) - else: - state = self.construct_mapping(node) - data.__dict__.update(state) - - def construct_undefined(self, node): - raise ConstructorError(None, None, - "could not determine a constructor for the tag %r" % node.tag.encode('utf-8'), - node.start_mark) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:null', - SafeConstructor.construct_yaml_null) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:bool', - SafeConstructor.construct_yaml_bool) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:int', - SafeConstructor.construct_yaml_int) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:float', - SafeConstructor.construct_yaml_float) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:binary', - SafeConstructor.construct_yaml_binary) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:timestamp', - SafeConstructor.construct_yaml_timestamp) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:omap', - SafeConstructor.construct_yaml_omap) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:pairs', - SafeConstructor.construct_yaml_pairs) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:set', - SafeConstructor.construct_yaml_set) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:str', - SafeConstructor.construct_yaml_str) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:seq', - SafeConstructor.construct_yaml_seq) - -SafeConstructor.add_constructor( - u'tag:yaml.org,2002:map', - SafeConstructor.construct_yaml_map) - -SafeConstructor.add_constructor(None, - SafeConstructor.construct_undefined) - -class Constructor(SafeConstructor): - - def construct_python_str(self, node): - return self.construct_scalar(node).encode('utf-8') - - def construct_python_unicode(self, node): - return self.construct_scalar(node) - - def construct_python_long(self, node): - return long(self.construct_yaml_int(node)) - - def construct_python_complex(self, node): - return complex(self.construct_scalar(node)) - - def construct_python_tuple(self, node): - return tuple(self.construct_sequence(node)) - - def find_python_module(self, name, mark): - if not name: - raise ConstructorError("while constructing a Python module", mark, - "expected non-empty name appended to the tag", mark) - try: - __import__(name) - except ImportError, exc: - raise ConstructorError("while constructing a Python module", mark, - "cannot find module %r (%s)" % (name.encode('utf-8'), exc), mark) - return sys.modules[name] - - def find_python_name(self, name, mark): - if not name: - raise ConstructorError("while constructing a Python object", mark, - "expected non-empty name appended to the tag", mark) - if u'.' in name: - # Python 2.4 only - #module_name, object_name = name.rsplit('.', 1) - items = name.split('.') - object_name = items.pop() - module_name = '.'.join(items) - else: - module_name = '__builtin__' - object_name = name - try: - __import__(module_name) - except ImportError, exc: - raise ConstructorError("while constructing a Python object", mark, - "cannot find module %r (%s)" % (module_name.encode('utf-8'), exc), mark) - module = sys.modules[module_name] - if not hasattr(module, object_name): - raise ConstructorError("while constructing a Python object", mark, - "cannot find %r in the module %r" % (object_name.encode('utf-8'), - module.__name__), mark) - return getattr(module, object_name) - - def construct_python_name(self, suffix, node): - value = self.construct_scalar(node) - if value: - raise ConstructorError("while constructing a Python name", node.start_mark, - "expected the empty value, but found %r" % value.encode('utf-8'), - node.start_mark) - return self.find_python_name(suffix, node.start_mark) - - def construct_python_module(self, suffix, node): - value = self.construct_scalar(node) - if value: - raise ConstructorError("while constructing a Python module", node.start_mark, - "expected the empty value, but found %r" % value.encode('utf-8'), - node.start_mark) - return self.find_python_module(suffix, node.start_mark) - - class classobj: pass - - def make_python_instance(self, suffix, node, - args=None, kwds=None, newobj=False): - if not args: - args = [] - if not kwds: - kwds = {} - cls = self.find_python_name(suffix, node.start_mark) - if newobj and isinstance(cls, type(self.classobj)) \ - and not args and not kwds: - instance = self.classobj() - instance.__class__ = cls - return instance - elif newobj and isinstance(cls, type): - return cls.__new__(cls, *args, **kwds) - else: - return cls(*args, **kwds) - - def set_python_instance_state(self, instance, state): - if hasattr(instance, '__setstate__'): - instance.__setstate__(state) - else: - slotstate = {} - if isinstance(state, tuple) and len(state) == 2: - state, slotstate = state - if hasattr(instance, '__dict__'): - instance.__dict__.update(state) - elif state: - slotstate.update(state) - for key, value in slotstate.items(): - setattr(object, key, value) - - def construct_python_object(self, suffix, node): - # Format: - # !!python/object:module.name { ... state ... } - instance = self.make_python_instance(suffix, node, newobj=True) - yield instance - deep = hasattr(instance, '__setstate__') - state = self.construct_mapping(node, deep=deep) - self.set_python_instance_state(instance, state) - - def construct_python_object_apply(self, suffix, node, newobj=False): - # Format: - # !!python/object/apply # (or !!python/object/new) - # args: [ ... arguments ... ] - # kwds: { ... keywords ... } - # state: ... state ... - # listitems: [ ... listitems ... ] - # dictitems: { ... dictitems ... } - # or short format: - # !!python/object/apply [ ... arguments ... ] - # The difference between !!python/object/apply and !!python/object/new - # is how an object is created, check make_python_instance for details. - if isinstance(node, SequenceNode): - args = self.construct_sequence(node, deep=True) - kwds = {} - state = {} - listitems = [] - dictitems = {} - else: - value = self.construct_mapping(node, deep=True) - args = value.get('args', []) - kwds = value.get('kwds', {}) - state = value.get('state', {}) - listitems = value.get('listitems', []) - dictitems = value.get('dictitems', {}) - instance = self.make_python_instance(suffix, node, args, kwds, newobj) - if state: - self.set_python_instance_state(instance, state) - if listitems: - instance.extend(listitems) - if dictitems: - for key in dictitems: - instance[key] = dictitems[key] - return instance - - def construct_python_object_new(self, suffix, node): - return self.construct_python_object_apply(suffix, node, newobj=True) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/none', - Constructor.construct_yaml_null) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/bool', - Constructor.construct_yaml_bool) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/str', - Constructor.construct_python_str) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/unicode', - Constructor.construct_python_unicode) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/int', - Constructor.construct_yaml_int) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/long', - Constructor.construct_python_long) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/float', - Constructor.construct_yaml_float) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/complex', - Constructor.construct_python_complex) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/list', - Constructor.construct_yaml_seq) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/tuple', - Constructor.construct_python_tuple) - -Constructor.add_constructor( - u'tag:yaml.org,2002:python/dict', - Constructor.construct_yaml_map) - -Constructor.add_multi_constructor( - u'tag:yaml.org,2002:python/name:', - Constructor.construct_python_name) - -Constructor.add_multi_constructor( - u'tag:yaml.org,2002:python/module:', - Constructor.construct_python_module) - -Constructor.add_multi_constructor( - u'tag:yaml.org,2002:python/object:', - Constructor.construct_python_object) - -Constructor.add_multi_constructor( - u'tag:yaml.org,2002:python/object/apply:', - Constructor.construct_python_object_apply) - -Constructor.add_multi_constructor( - u'tag:yaml.org,2002:python/object/new:', - Constructor.construct_python_object_new) - diff --git a/plugins_available/util/yaml/cyaml.py b/plugins_available/util/yaml/cyaml.py deleted file mode 100644 index 68dcd75..0000000 --- a/plugins_available/util/yaml/cyaml.py +++ /dev/null @@ -1,85 +0,0 @@ - -__all__ = ['CBaseLoader', 'CSafeLoader', 'CLoader', - 'CBaseDumper', 'CSafeDumper', 'CDumper'] - -from _yaml import CParser, CEmitter - -from constructor import * - -from serializer import * -from representer import * - -from resolver import * - -class CBaseLoader(CParser, BaseConstructor, BaseResolver): - - def __init__(self, stream): - CParser.__init__(self, stream) - BaseConstructor.__init__(self) - BaseResolver.__init__(self) - -class CSafeLoader(CParser, SafeConstructor, Resolver): - - def __init__(self, stream): - CParser.__init__(self, stream) - SafeConstructor.__init__(self) - Resolver.__init__(self) - -class CLoader(CParser, Constructor, Resolver): - - def __init__(self, stream): - CParser.__init__(self, stream) - Constructor.__init__(self) - Resolver.__init__(self) - -class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver): - - def __init__(self, stream, - default_style=None, default_flow_style=None, - canonical=None, indent=None, width=None, - allow_unicode=None, line_break=None, - encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): - CEmitter.__init__(self, stream, canonical=canonical, - indent=indent, width=width, encoding=encoding, - allow_unicode=allow_unicode, line_break=line_break, - explicit_start=explicit_start, explicit_end=explicit_end, - version=version, tags=tags) - Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) - Resolver.__init__(self) - -class CSafeDumper(CEmitter, SafeRepresenter, Resolver): - - def __init__(self, stream, - default_style=None, default_flow_style=None, - canonical=None, indent=None, width=None, - allow_unicode=None, line_break=None, - encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): - CEmitter.__init__(self, stream, canonical=canonical, - indent=indent, width=width, encoding=encoding, - allow_unicode=allow_unicode, line_break=line_break, - explicit_start=explicit_start, explicit_end=explicit_end, - version=version, tags=tags) - SafeRepresenter.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) - Resolver.__init__(self) - -class CDumper(CEmitter, Serializer, Representer, Resolver): - - def __init__(self, stream, - default_style=None, default_flow_style=None, - canonical=None, indent=None, width=None, - allow_unicode=None, line_break=None, - encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): - CEmitter.__init__(self, stream, canonical=canonical, - indent=indent, width=width, encoding=encoding, - allow_unicode=allow_unicode, line_break=line_break, - explicit_start=explicit_start, explicit_end=explicit_end, - version=version, tags=tags) - Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) - Resolver.__init__(self) - diff --git a/plugins_available/util/yaml/dumper.py b/plugins_available/util/yaml/dumper.py deleted file mode 100644 index f811d2c..0000000 --- a/plugins_available/util/yaml/dumper.py +++ /dev/null @@ -1,62 +0,0 @@ - -__all__ = ['BaseDumper', 'SafeDumper', 'Dumper'] - -from emitter import * -from serializer import * -from representer import * -from resolver import * - -class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver): - - def __init__(self, stream, - default_style=None, default_flow_style=None, - canonical=None, indent=None, width=None, - allow_unicode=None, line_break=None, - encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): - Emitter.__init__(self, stream, canonical=canonical, - indent=indent, width=width, - allow_unicode=allow_unicode, line_break=line_break) - Serializer.__init__(self, encoding=encoding, - explicit_start=explicit_start, explicit_end=explicit_end, - version=version, tags=tags) - Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) - Resolver.__init__(self) - -class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver): - - def __init__(self, stream, - default_style=None, default_flow_style=None, - canonical=None, indent=None, width=None, - allow_unicode=None, line_break=None, - encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): - Emitter.__init__(self, stream, canonical=canonical, - indent=indent, width=width, - allow_unicode=allow_unicode, line_break=line_break) - Serializer.__init__(self, encoding=encoding, - explicit_start=explicit_start, explicit_end=explicit_end, - version=version, tags=tags) - SafeRepresenter.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) - Resolver.__init__(self) - -class Dumper(Emitter, Serializer, Representer, Resolver): - - def __init__(self, stream, - default_style=None, default_flow_style=None, - canonical=None, indent=None, width=None, - allow_unicode=None, line_break=None, - encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): - Emitter.__init__(self, stream, canonical=canonical, - indent=indent, width=width, - allow_unicode=allow_unicode, line_break=line_break) - Serializer.__init__(self, encoding=encoding, - explicit_start=explicit_start, explicit_end=explicit_end, - version=version, tags=tags) - Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) - Resolver.__init__(self) - diff --git a/plugins_available/util/yaml/emitter.py b/plugins_available/util/yaml/emitter.py deleted file mode 100644 index 4cb2c8a..0000000 --- a/plugins_available/util/yaml/emitter.py +++ /dev/null @@ -1,1135 +0,0 @@ - -# Emitter expects events obeying the following grammar: -# stream ::= STREAM-START document* STREAM-END -# document ::= DOCUMENT-START node DOCUMENT-END -# node ::= SCALAR | sequence | mapping -# sequence ::= SEQUENCE-START node* SEQUENCE-END -# mapping ::= MAPPING-START (node node)* MAPPING-END - -__all__ = ['Emitter', 'EmitterError'] - -from error import YAMLError -from events import * - -class EmitterError(YAMLError): - pass - -class ScalarAnalysis(object): - def __init__(self, scalar, empty, multiline, - allow_flow_plain, allow_block_plain, - allow_single_quoted, allow_double_quoted, - allow_block): - self.scalar = scalar - self.empty = empty - self.multiline = multiline - self.allow_flow_plain = allow_flow_plain - self.allow_block_plain = allow_block_plain - self.allow_single_quoted = allow_single_quoted - self.allow_double_quoted = allow_double_quoted - self.allow_block = allow_block - -class Emitter(object): - - DEFAULT_TAG_PREFIXES = { - u'!' : u'!', - u'tag:yaml.org,2002:' : u'!!', - } - - def __init__(self, stream, canonical=None, indent=None, width=None, - allow_unicode=None, line_break=None): - - # The stream should have the methods `write` and possibly `flush`. - self.stream = stream - - # Encoding can be overriden by STREAM-START. - self.encoding = None - - # Emitter is a state machine with a stack of states to handle nested - # structures. - self.states = [] - self.state = self.expect_stream_start - - # Current event and the event queue. - self.events = [] - self.event = None - - # The current indentation level and the stack of previous indents. - self.indents = [] - self.indent = None - - # Flow level. - self.flow_level = 0 - - # Contexts. - self.root_context = False - self.sequence_context = False - self.mapping_context = False - self.simple_key_context = False - - # Characteristics of the last emitted character: - # - current position. - # - is it a whitespace? - # - is it an indention character - # (indentation space, '-', '?', or ':')? - self.line = 0 - self.column = 0 - self.whitespace = True - self.indention = True - - # Whether the document requires an explicit document indicator - self.open_ended = False - - # Formatting details. - self.canonical = canonical - self.allow_unicode = allow_unicode - self.best_indent = 2 - if indent and 1 < indent < 10: - self.best_indent = indent - self.best_width = 80 - if width and width > self.best_indent*2: - self.best_width = width - self.best_line_break = u'\n' - if line_break in [u'\r', u'\n', u'\r\n']: - self.best_line_break = line_break - - # Tag prefixes. - self.tag_prefixes = None - - # Prepared anchor and tag. - self.prepared_anchor = None - self.prepared_tag = None - - # Scalar analysis and style. - self.analysis = None - self.style = None - - def emit(self, event): - self.events.append(event) - while not self.need_more_events(): - self.event = self.events.pop(0) - self.state() - self.event = None - - # In some cases, we wait for a few next events before emitting. - - def need_more_events(self): - if not self.events: - return True - event = self.events[0] - if isinstance(event, DocumentStartEvent): - return self.need_events(1) - elif isinstance(event, SequenceStartEvent): - return self.need_events(2) - elif isinstance(event, MappingStartEvent): - return self.need_events(3) - else: - return False - - def need_events(self, count): - level = 0 - for event in self.events[1:]: - if isinstance(event, (DocumentStartEvent, CollectionStartEvent)): - level += 1 - elif isinstance(event, (DocumentEndEvent, CollectionEndEvent)): - level -= 1 - elif isinstance(event, StreamEndEvent): - level = -1 - if level < 0: - return False - return (len(self.events) < count+1) - - def increase_indent(self, flow=False, indentless=False): - self.indents.append(self.indent) - if self.indent is None: - if flow: - self.indent = self.best_indent - else: - self.indent = 0 - elif not indentless: - self.indent += self.best_indent - - # States. - - # Stream handlers. - - def expect_stream_start(self): - if isinstance(self.event, StreamStartEvent): - if self.event.encoding and not getattr(self.stream, 'encoding', None): - self.encoding = self.event.encoding - self.write_stream_start() - self.state = self.expect_first_document_start - else: - raise EmitterError("expected StreamStartEvent, but got %s" - % self.event) - - def expect_nothing(self): - raise EmitterError("expected nothing, but got %s" % self.event) - - # Document handlers. - - def expect_first_document_start(self): - return self.expect_document_start(first=True) - - def expect_document_start(self, first=False): - if isinstance(self.event, DocumentStartEvent): - if (self.event.version or self.event.tags) and self.open_ended: - self.write_indicator(u'...', True) - self.write_indent() - if self.event.version: - version_text = self.prepare_version(self.event.version) - self.write_version_directive(version_text) - self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy() - if self.event.tags: - handles = self.event.tags.keys() - handles.sort() - for handle in handles: - prefix = self.event.tags[handle] - self.tag_prefixes[prefix] = handle - handle_text = self.prepare_tag_handle(handle) - prefix_text = self.prepare_tag_prefix(prefix) - self.write_tag_directive(handle_text, prefix_text) - implicit = (first and not self.event.explicit and not self.canonical - and not self.event.version and not self.event.tags - and not self.check_empty_document()) - if not implicit: - self.write_indent() - self.write_indicator(u'---', True) - if self.canonical: - self.write_indent() - self.state = self.expect_document_root - elif isinstance(self.event, StreamEndEvent): - if self.open_ended: - self.write_indicator(u'...', True) - self.write_indent() - self.write_stream_end() - self.state = self.expect_nothing - else: - raise EmitterError("expected DocumentStartEvent, but got %s" - % self.event) - - def expect_document_end(self): - if isinstance(self.event, DocumentEndEvent): - self.write_indent() - if self.event.explicit: - self.write_indicator(u'...', True) - self.write_indent() - self.flush_stream() - self.state = self.expect_document_start - else: - raise EmitterError("expected DocumentEndEvent, but got %s" - % self.event) - - def expect_document_root(self): - self.states.append(self.expect_document_end) - self.expect_node(root=True) - - # Node handlers. - - def expect_node(self, root=False, sequence=False, mapping=False, - simple_key=False): - self.root_context = root - self.sequence_context = sequence - self.mapping_context = mapping - self.simple_key_context = simple_key - if isinstance(self.event, AliasEvent): - self.expect_alias() - elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)): - self.process_anchor(u'&') - self.process_tag() - if isinstance(self.event, ScalarEvent): - self.expect_scalar() - elif isinstance(self.event, SequenceStartEvent): - if self.flow_level or self.canonical or self.event.flow_style \ - or self.check_empty_sequence(): - self.expect_flow_sequence() - else: - self.expect_block_sequence() - elif isinstance(self.event, MappingStartEvent): - if self.flow_level or self.canonical or self.event.flow_style \ - or self.check_empty_mapping(): - self.expect_flow_mapping() - else: - self.expect_block_mapping() - else: - raise EmitterError("expected NodeEvent, but got %s" % self.event) - - def expect_alias(self): - if self.event.anchor is None: - raise EmitterError("anchor is not specified for alias") - self.process_anchor(u'*') - self.state = self.states.pop() - - def expect_scalar(self): - self.increase_indent(flow=True) - self.process_scalar() - self.indent = self.indents.pop() - self.state = self.states.pop() - - # Flow sequence handlers. - - def expect_flow_sequence(self): - self.write_indicator(u'[', True, whitespace=True) - self.flow_level += 1 - self.increase_indent(flow=True) - self.state = self.expect_first_flow_sequence_item - - def expect_first_flow_sequence_item(self): - if isinstance(self.event, SequenceEndEvent): - self.indent = self.indents.pop() - self.flow_level -= 1 - self.write_indicator(u']', False) - self.state = self.states.pop() - else: - if self.canonical or self.column > self.best_width: - self.write_indent() - self.states.append(self.expect_flow_sequence_item) - self.expect_node(sequence=True) - - def expect_flow_sequence_item(self): - if isinstance(self.event, SequenceEndEvent): - self.indent = self.indents.pop() - self.flow_level -= 1 - if self.canonical: - self.write_indicator(u',', False) - self.write_indent() - self.write_indicator(u']', False) - self.state = self.states.pop() - else: - self.write_indicator(u',', False) - if self.canonical or self.column > self.best_width: - self.write_indent() - self.states.append(self.expect_flow_sequence_item) - self.expect_node(sequence=True) - - # Flow mapping handlers. - - def expect_flow_mapping(self): - self.write_indicator(u'{', True, whitespace=True) - self.flow_level += 1 - self.increase_indent(flow=True) - self.state = self.expect_first_flow_mapping_key - - def expect_first_flow_mapping_key(self): - if isinstance(self.event, MappingEndEvent): - self.indent = self.indents.pop() - self.flow_level -= 1 - self.write_indicator(u'}', False) - self.state = self.states.pop() - else: - if self.canonical or self.column > self.best_width: - self.write_indent() - if not self.canonical and self.check_simple_key(): - self.states.append(self.expect_flow_mapping_simple_value) - self.expect_node(mapping=True, simple_key=True) - else: - self.write_indicator(u'?', True) - self.states.append(self.expect_flow_mapping_value) - self.expect_node(mapping=True) - - def expect_flow_mapping_key(self): - if isinstance(self.event, MappingEndEvent): - self.indent = self.indents.pop() - self.flow_level -= 1 - if self.canonical: - self.write_indicator(u',', False) - self.write_indent() - self.write_indicator(u'}', False) - self.state = self.states.pop() - else: - self.write_indicator(u',', False) - if self.canonical or self.column > self.best_width: - self.write_indent() - if not self.canonical and self.check_simple_key(): - self.states.append(self.expect_flow_mapping_simple_value) - self.expect_node(mapping=True, simple_key=True) - else: - self.write_indicator(u'?', True) - self.states.append(self.expect_flow_mapping_value) - self.expect_node(mapping=True) - - def expect_flow_mapping_simple_value(self): - self.write_indicator(u':', False) - self.states.append(self.expect_flow_mapping_key) - self.expect_node(mapping=True) - - def expect_flow_mapping_value(self): - if self.canonical or self.column > self.best_width: - self.write_indent() - self.write_indicator(u':', True) - self.states.append(self.expect_flow_mapping_key) - self.expect_node(mapping=True) - - # Block sequence handlers. - - def expect_block_sequence(self): - indentless = (self.mapping_context and not self.indention) - self.increase_indent(flow=False, indentless=indentless) - self.state = self.expect_first_block_sequence_item - - def expect_first_block_sequence_item(self): - return self.expect_block_sequence_item(first=True) - - def expect_block_sequence_item(self, first=False): - if not first and isinstance(self.event, SequenceEndEvent): - self.indent = self.indents.pop() - self.state = self.states.pop() - else: - self.write_indent() - self.write_indicator(u'-', True, indention=True) - self.states.append(self.expect_block_sequence_item) - self.expect_node(sequence=True) - - # Block mapping handlers. - - def expect_block_mapping(self): - self.increase_indent(flow=False) - self.state = self.expect_first_block_mapping_key - - def expect_first_block_mapping_key(self): - return self.expect_block_mapping_key(first=True) - - def expect_block_mapping_key(self, first=False): - if not first and isinstance(self.event, MappingEndEvent): - self.indent = self.indents.pop() - self.state = self.states.pop() - else: - self.write_indent() - if self.check_simple_key(): - self.states.append(self.expect_block_mapping_simple_value) - self.expect_node(mapping=True, simple_key=True) - else: - self.write_indicator(u'?', True, indention=True) - self.states.append(self.expect_block_mapping_value) - self.expect_node(mapping=True) - - def expect_block_mapping_simple_value(self): - self.write_indicator(u':', False) - self.states.append(self.expect_block_mapping_key) - self.expect_node(mapping=True) - - def expect_block_mapping_value(self): - self.write_indent() - self.write_indicator(u':', True, indention=True) - self.states.append(self.expect_block_mapping_key) - self.expect_node(mapping=True) - - # Checkers. - - def check_empty_sequence(self): - return (isinstance(self.event, SequenceStartEvent) and self.events - and isinstance(self.events[0], SequenceEndEvent)) - - def check_empty_mapping(self): - return (isinstance(self.event, MappingStartEvent) and self.events - and isinstance(self.events[0], MappingEndEvent)) - - def check_empty_document(self): - if not isinstance(self.event, DocumentStartEvent) or not self.events: - return False - event = self.events[0] - return (isinstance(event, ScalarEvent) and event.anchor is None - and event.tag is None and event.implicit and event.value == u'') - - def check_simple_key(self): - length = 0 - if isinstance(self.event, NodeEvent) and self.event.anchor is not None: - if self.prepared_anchor is None: - self.prepared_anchor = self.prepare_anchor(self.event.anchor) - length += len(self.prepared_anchor) - if isinstance(self.event, (ScalarEvent, CollectionStartEvent)) \ - and self.event.tag is not None: - if self.prepared_tag is None: - self.prepared_tag = self.prepare_tag(self.event.tag) - length += len(self.prepared_tag) - if isinstance(self.event, ScalarEvent): - if self.analysis is None: - self.analysis = self.analyze_scalar(self.event.value) - length += len(self.analysis.scalar) - return (length < 128 and (isinstance(self.event, AliasEvent) - or (isinstance(self.event, ScalarEvent) - and not self.analysis.empty and not self.analysis.multiline) - or self.check_empty_sequence() or self.check_empty_mapping())) - - # Anchor, Tag, and Scalar processors. - - def process_anchor(self, indicator): - if self.event.anchor is None: - self.prepared_anchor = None - return - if self.prepared_anchor is None: - self.prepared_anchor = self.prepare_anchor(self.event.anchor) - if self.prepared_anchor: - self.write_indicator(indicator+self.prepared_anchor, True) - self.prepared_anchor = None - - def process_tag(self): - tag = self.event.tag - if isinstance(self.event, ScalarEvent): - if self.style is None: - self.style = self.choose_scalar_style() - if ((not self.canonical or tag is None) and - ((self.style == '' and self.event.implicit[0]) - or (self.style != '' and self.event.implicit[1]))): - self.prepared_tag = None - return - if self.event.implicit[0] and tag is None: - tag = u'!' - self.prepared_tag = None - else: - if (not self.canonical or tag is None) and self.event.implicit: - self.prepared_tag = None - return - if tag is None: - raise EmitterError("tag is not specified") - if self.prepared_tag is None: - self.prepared_tag = self.prepare_tag(tag) - if self.prepared_tag: - self.write_indicator(self.prepared_tag, True) - self.prepared_tag = None - - def choose_scalar_style(self): - if self.analysis is None: - self.analysis = self.analyze_scalar(self.event.value) - if self.event.style == '"' or self.canonical: - return '"' - if not self.event.style and self.event.implicit[0]: - if (not (self.simple_key_context and - (self.analysis.empty or self.analysis.multiline)) - and (self.flow_level and self.analysis.allow_flow_plain - or (not self.flow_level and self.analysis.allow_block_plain))): - return '' - if self.event.style and self.event.style in '|>': - if (not self.flow_level and not self.simple_key_context - and self.analysis.allow_block): - return self.event.style - if not self.event.style or self.event.style == '\'': - if (self.analysis.allow_single_quoted and - not (self.simple_key_context and self.analysis.multiline)): - return '\'' - return '"' - - def process_scalar(self): - if self.analysis is None: - self.analysis = self.analyze_scalar(self.event.value) - if self.style is None: - self.style = self.choose_scalar_style() - split = (not self.simple_key_context) - #if self.analysis.multiline and split \ - # and (not self.style or self.style in '\'\"'): - # self.write_indent() - if self.style == '"': - self.write_double_quoted(self.analysis.scalar, split) - elif self.style == '\'': - self.write_single_quoted(self.analysis.scalar, split) - elif self.style == '>': - self.write_folded(self.analysis.scalar) - elif self.style == '|': - self.write_literal(self.analysis.scalar) - else: - self.write_plain(self.analysis.scalar, split) - self.analysis = None - self.style = None - - # Analyzers. - - def prepare_version(self, version): - major, minor = version - if major != 1: - raise EmitterError("unsupported YAML version: %d.%d" % (major, minor)) - return u'%d.%d' % (major, minor) - - def prepare_tag_handle(self, handle): - if not handle: - raise EmitterError("tag handle must not be empty") - if handle[0] != u'!' or handle[-1] != u'!': - raise EmitterError("tag handle must start and end with '!': %r" - % (handle.encode('utf-8'))) - for ch in handle[1:-1]: - if not (u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ - or ch in u'-_'): - raise EmitterError("invalid character %r in the tag handle: %r" - % (ch.encode('utf-8'), handle.encode('utf-8'))) - return handle - - def prepare_tag_prefix(self, prefix): - if not prefix: - raise EmitterError("tag prefix must not be empty") - chunks = [] - start = end = 0 - if prefix[0] == u'!': - end = 1 - while end < len(prefix): - ch = prefix[end] - if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ - or ch in u'-;/?!:@&=+$,_.~*\'()[]': - end += 1 - else: - if start < end: - chunks.append(prefix[start:end]) - start = end = end+1 - data = ch.encode('utf-8') - for ch in data: - chunks.append(u'%%%02X' % ord(ch)) - if start < end: - chunks.append(prefix[start:end]) - return u''.join(chunks) - - def prepare_tag(self, tag): - if not tag: - raise EmitterError("tag must not be empty") - if tag == u'!': - return tag - handle = None - suffix = tag - prefixes = self.tag_prefixes.keys() - prefixes.sort() - for prefix in prefixes: - if tag.startswith(prefix) \ - and (prefix == u'!' or len(prefix) < len(tag)): - handle = self.tag_prefixes[prefix] - suffix = tag[len(prefix):] - chunks = [] - start = end = 0 - while end < len(suffix): - ch = suffix[end] - if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ - or ch in u'-;/?:@&=+$,_.~*\'()[]' \ - or (ch == u'!' and handle != u'!'): - end += 1 - else: - if start < end: - chunks.append(suffix[start:end]) - start = end = end+1 - data = ch.encode('utf-8') - for ch in data: - chunks.append(u'%%%02X' % ord(ch)) - if start < end: - chunks.append(suffix[start:end]) - suffix_text = u''.join(chunks) - if handle: - return u'%s%s' % (handle, suffix_text) - else: - return u'!<%s>' % suffix_text - - def prepare_anchor(self, anchor): - if not anchor: - raise EmitterError("anchor must not be empty") - for ch in anchor: - if not (u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ - or ch in u'-_'): - raise EmitterError("invalid character %r in the anchor: %r" - % (ch.encode('utf-8'), anchor.encode('utf-8'))) - return anchor - - def analyze_scalar(self, scalar): - - # Empty scalar is a special case. - if not scalar: - return ScalarAnalysis(scalar=scalar, empty=True, multiline=False, - allow_flow_plain=False, allow_block_plain=True, - allow_single_quoted=True, allow_double_quoted=True, - allow_block=False) - - # Indicators and special characters. - block_indicators = False - flow_indicators = False - line_breaks = False - special_characters = False - - # Important whitespace combinations. - leading_space = False - leading_break = False - trailing_space = False - trailing_break = False - break_space = False - space_break = False - - # Check document indicators. - if scalar.startswith(u'---') or scalar.startswith(u'...'): - block_indicators = True - flow_indicators = True - - # First character or preceded by a whitespace. - preceeded_by_whitespace = True - - # Last character or followed by a whitespace. - followed_by_whitespace = (len(scalar) == 1 or - scalar[1] in u'\0 \t\r\n\x85\u2028\u2029') - - # The previous character is a space. - previous_space = False - - # The previous character is a break. - previous_break = False - - index = 0 - while index < len(scalar): - ch = scalar[index] - - # Check for indicators. - if index == 0: - # Leading indicators are special characters. - if ch in u'#,[]{}&*!|>\'\"%@`': - flow_indicators = True - block_indicators = True - if ch in u'?:': - flow_indicators = True - if followed_by_whitespace: - block_indicators = True - if ch == u'-' and followed_by_whitespace: - flow_indicators = True - block_indicators = True - else: - # Some indicators cannot appear within a scalar as well. - if ch in u',?[]{}': - flow_indicators = True - if ch == u':': - flow_indicators = True - if followed_by_whitespace: - block_indicators = True - if ch == u'#' and preceeded_by_whitespace: - flow_indicators = True - block_indicators = True - - # Check for line breaks, special, and unicode characters. - if ch in u'\n\x85\u2028\u2029': - line_breaks = True - if not (ch == u'\n' or u'\x20' <= ch <= u'\x7E'): - if (ch == u'\x85' or u'\xA0' <= ch <= u'\uD7FF' - or u'\uE000' <= ch <= u'\uFFFD') and ch != u'\uFEFF': - unicode_characters = True - if not self.allow_unicode: - special_characters = True - else: - special_characters = True - - # Detect important whitespace combinations. - if ch == u' ': - if index == 0: - leading_space = True - if index == len(scalar)-1: - trailing_space = True - if previous_break: - break_space = True - previous_space = True - previous_break = False - elif ch in u'\n\x85\u2028\u2029': - if index == 0: - leading_break = True - if index == len(scalar)-1: - trailing_break = True - if previous_space: - space_break = True - previous_space = False - previous_break = True - else: - previous_space = False - previous_break = False - - # Prepare for the next character. - index += 1 - preceeded_by_whitespace = (ch in u'\0 \t\r\n\x85\u2028\u2029') - followed_by_whitespace = (index+1 >= len(scalar) or - scalar[index+1] in u'\0 \t\r\n\x85\u2028\u2029') - - # Let's decide what styles are allowed. - allow_flow_plain = True - allow_block_plain = True - allow_single_quoted = True - allow_double_quoted = True - allow_block = True - - # Leading and trailing whitespaces are bad for plain scalars. - if (leading_space or leading_break - or trailing_space or trailing_break): - allow_flow_plain = allow_block_plain = False - - # We do not permit trailing spaces for block scalars. - if trailing_space: - allow_block = False - - # Spaces at the beginning of a new line are only acceptable for block - # scalars. - if break_space: - allow_flow_plain = allow_block_plain = allow_single_quoted = False - - # Spaces followed by breaks, as well as special character are only - # allowed for double quoted scalars. - if space_break or special_characters: - allow_flow_plain = allow_block_plain = \ - allow_single_quoted = allow_block = False - - # Although the plain scalar writer supports breaks, we never emit - # multiline plain scalars. - if line_breaks: - allow_flow_plain = allow_block_plain = False - - # Flow indicators are forbidden for flow plain scalars. - if flow_indicators: - allow_flow_plain = False - - # Block indicators are forbidden for block plain scalars. - if block_indicators: - allow_block_plain = False - - return ScalarAnalysis(scalar=scalar, - empty=False, multiline=line_breaks, - allow_flow_plain=allow_flow_plain, - allow_block_plain=allow_block_plain, - allow_single_quoted=allow_single_quoted, - allow_double_quoted=allow_double_quoted, - allow_block=allow_block) - - # Writers. - - def flush_stream(self): - if hasattr(self.stream, 'flush'): - self.stream.flush() - - def write_stream_start(self): - # Write BOM if needed. - if self.encoding and self.encoding.startswith('utf-16'): - self.stream.write(u'\uFEFF'.encode(self.encoding)) - - def write_stream_end(self): - self.flush_stream() - - def write_indicator(self, indicator, need_whitespace, - whitespace=False, indention=False): - if self.whitespace or not need_whitespace: - data = indicator - else: - data = u' '+indicator - self.whitespace = whitespace - self.indention = self.indention and indention - self.column += len(data) - self.open_ended = False - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - - def write_indent(self): - indent = self.indent or 0 - if not self.indention or self.column > indent \ - or (self.column == indent and not self.whitespace): - self.write_line_break() - if self.column < indent: - self.whitespace = True - data = u' '*(indent-self.column) - self.column = indent - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - - def write_line_break(self, data=None): - if data is None: - data = self.best_line_break - self.whitespace = True - self.indention = True - self.line += 1 - self.column = 0 - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - - def write_version_directive(self, version_text): - data = u'%%YAML %s' % version_text - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - self.write_line_break() - - def write_tag_directive(self, handle_text, prefix_text): - data = u'%%TAG %s %s' % (handle_text, prefix_text) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - self.write_line_break() - - # Scalar streams. - - def write_single_quoted(self, text, split=True): - self.write_indicator(u'\'', True) - spaces = False - breaks = False - start = end = 0 - while end <= len(text): - ch = None - if end < len(text): - ch = text[end] - if spaces: - if ch is None or ch != u' ': - if start+1 == end and self.column > self.best_width and split \ - and start != 0 and end != len(text): - self.write_indent() - else: - data = text[start:end] - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - start = end - elif breaks: - if ch is None or ch not in u'\n\x85\u2028\u2029': - if text[start] == u'\n': - self.write_line_break() - for br in text[start:end]: - if br == u'\n': - self.write_line_break() - else: - self.write_line_break(br) - self.write_indent() - start = end - else: - if ch is None or ch in u' \n\x85\u2028\u2029' or ch == u'\'': - if start < end: - data = text[start:end] - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - start = end - if ch == u'\'': - data = u'\'\'' - self.column += 2 - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - start = end + 1 - if ch is not None: - spaces = (ch == u' ') - breaks = (ch in u'\n\x85\u2028\u2029') - end += 1 - self.write_indicator(u'\'', False) - - ESCAPE_REPLACEMENTS = { - u'\0': u'0', - u'\x07': u'a', - u'\x08': u'b', - u'\x09': u't', - u'\x0A': u'n', - u'\x0B': u'v', - u'\x0C': u'f', - u'\x0D': u'r', - u'\x1B': u'e', - u'\"': u'\"', - u'\\': u'\\', - u'\x85': u'N', - u'\xA0': u'_', - u'\u2028': u'L', - u'\u2029': u'P', - } - - def write_double_quoted(self, text, split=True): - self.write_indicator(u'"', True) - start = end = 0 - while end <= len(text): - ch = None - if end < len(text): - ch = text[end] - if ch is None or ch in u'"\\\x85\u2028\u2029\uFEFF' \ - or not (u'\x20' <= ch <= u'\x7E' - or (self.allow_unicode - and (u'\xA0' <= ch <= u'\uD7FF' - or u'\uE000' <= ch <= u'\uFFFD'))): - if start < end: - data = text[start:end] - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - start = end - if ch is not None: - if ch in self.ESCAPE_REPLACEMENTS: - data = u'\\'+self.ESCAPE_REPLACEMENTS[ch] - elif ch <= u'\xFF': - data = u'\\x%02X' % ord(ch) - elif ch <= u'\uFFFF': - data = u'\\u%04X' % ord(ch) - else: - data = u'\\U%08X' % ord(ch) - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - start = end+1 - if 0 < end < len(text)-1 and (ch == u' ' or start >= end) \ - and self.column+(end-start) > self.best_width and split: - data = text[start:end]+u'\\' - if start < end: - start = end - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - self.write_indent() - self.whitespace = False - self.indention = False - if text[start] == u' ': - data = u'\\' - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - end += 1 - self.write_indicator(u'"', False) - - def determine_block_hints(self, text): - hints = u'' - if text: - if text[0] in u' \n\x85\u2028\u2029': - hints += unicode(self.best_indent) - if text[-1] not in u'\n\x85\u2028\u2029': - hints += u'-' - elif len(text) == 1 or text[-2] in u'\n\x85\u2028\u2029': - hints += u'+' - return hints - - def write_folded(self, text): - hints = self.determine_block_hints(text) - self.write_indicator(u'>'+hints, True) - if hints[-1:] == u'+': - self.open_ended = True - self.write_line_break() - leading_space = True - spaces = False - breaks = True - start = end = 0 - while end <= len(text): - ch = None - if end < len(text): - ch = text[end] - if breaks: - if ch is None or ch not in u'\n\x85\u2028\u2029': - if not leading_space and ch is not None and ch != u' ' \ - and text[start] == u'\n': - self.write_line_break() - leading_space = (ch == u' ') - for br in text[start:end]: - if br == u'\n': - self.write_line_break() - else: - self.write_line_break(br) - if ch is not None: - self.write_indent() - start = end - elif spaces: - if ch != u' ': - if start+1 == end and self.column > self.best_width: - self.write_indent() - else: - data = text[start:end] - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - start = end - else: - if ch is None or ch in u' \n\x85\u2028\u2029': - data = text[start:end] - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - if ch is None: - self.write_line_break() - start = end - if ch is not None: - breaks = (ch in u'\n\x85\u2028\u2029') - spaces = (ch == u' ') - end += 1 - - def write_literal(self, text): - hints = self.determine_block_hints(text) - self.write_indicator(u'|'+hints, True) - if hints[-1:] == u'+': - self.open_ended = True - self.write_line_break() - breaks = True - start = end = 0 - while end <= len(text): - ch = None - if end < len(text): - ch = text[end] - if breaks: - if ch is None or ch not in u'\n\x85\u2028\u2029': - for br in text[start:end]: - if br == u'\n': - self.write_line_break() - else: - self.write_line_break(br) - if ch is not None: - self.write_indent() - start = end - else: - if ch is None or ch in u'\n\x85\u2028\u2029': - data = text[start:end] - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - if ch is None: - self.write_line_break() - start = end - if ch is not None: - breaks = (ch in u'\n\x85\u2028\u2029') - end += 1 - - def write_plain(self, text, split=True): - if self.root_context: - self.open_ended = True - if not text: - return - if not self.whitespace: - data = u' ' - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - self.whitespace = False - self.indention = False - spaces = False - breaks = False - start = end = 0 - while end <= len(text): - ch = None - if end < len(text): - ch = text[end] - if spaces: - if ch != u' ': - if start+1 == end and self.column > self.best_width and split: - self.write_indent() - self.whitespace = False - self.indention = False - else: - data = text[start:end] - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - start = end - elif breaks: - if ch not in u'\n\x85\u2028\u2029': - if text[start] == u'\n': - self.write_line_break() - for br in text[start:end]: - if br == u'\n': - self.write_line_break() - else: - self.write_line_break(br) - self.write_indent() - self.whitespace = False - self.indention = False - start = end - else: - if ch is None or ch in u' \n\x85\u2028\u2029': - data = text[start:end] - self.column += len(data) - if self.encoding: - data = data.encode(self.encoding) - self.stream.write(data) - start = end - if ch is not None: - spaces = (ch == u' ') - breaks = (ch in u'\n\x85\u2028\u2029') - end += 1 - diff --git a/plugins_available/util/yaml/error.py b/plugins_available/util/yaml/error.py deleted file mode 100644 index 577686d..0000000 --- a/plugins_available/util/yaml/error.py +++ /dev/null @@ -1,75 +0,0 @@ - -__all__ = ['Mark', 'YAMLError', 'MarkedYAMLError'] - -class Mark(object): - - def __init__(self, name, index, line, column, buffer, pointer): - self.name = name - self.index = index - self.line = line - self.column = column - self.buffer = buffer - self.pointer = pointer - - def get_snippet(self, indent=4, max_length=75): - if self.buffer is None: - return None - head = '' - start = self.pointer - while start > 0 and self.buffer[start-1] not in u'\0\r\n\x85\u2028\u2029': - start -= 1 - if self.pointer-start > max_length/2-1: - head = ' ... ' - start += 5 - break - tail = '' - end = self.pointer - while end < len(self.buffer) and self.buffer[end] not in u'\0\r\n\x85\u2028\u2029': - end += 1 - if end-self.pointer > max_length/2-1: - tail = ' ... ' - end -= 5 - break - snippet = self.buffer[start:end].encode('utf-8') - return ' '*indent + head + snippet + tail + '\n' \ - + ' '*(indent+self.pointer-start+len(head)) + '^' - - def __str__(self): - snippet = self.get_snippet() - where = " in \"%s\", line %d, column %d" \ - % (self.name, self.line+1, self.column+1) - if snippet is not None: - where += ":\n"+snippet - return where - -class YAMLError(Exception): - pass - -class MarkedYAMLError(YAMLError): - - def __init__(self, context=None, context_mark=None, - problem=None, problem_mark=None, note=None): - self.context = context - self.context_mark = context_mark - self.problem = problem - self.problem_mark = problem_mark - self.note = note - - def __str__(self): - lines = [] - if self.context is not None: - lines.append(self.context) - if self.context_mark is not None \ - and (self.problem is None or self.problem_mark is None - or self.context_mark.name != self.problem_mark.name - or self.context_mark.line != self.problem_mark.line - or self.context_mark.column != self.problem_mark.column): - lines.append(str(self.context_mark)) - if self.problem is not None: - lines.append(self.problem) - if self.problem_mark is not None: - lines.append(str(self.problem_mark)) - if self.note is not None: - lines.append(self.note) - return '\n'.join(lines) - diff --git a/plugins_available/util/yaml/events.py b/plugins_available/util/yaml/events.py deleted file mode 100644 index f79ad38..0000000 --- a/plugins_available/util/yaml/events.py +++ /dev/null @@ -1,86 +0,0 @@ - -# Abstract classes. - -class Event(object): - def __init__(self, start_mark=None, end_mark=None): - self.start_mark = start_mark - self.end_mark = end_mark - def __repr__(self): - attributes = [key for key in ['anchor', 'tag', 'implicit', 'value'] - if hasattr(self, key)] - arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) - for key in attributes]) - return '%s(%s)' % (self.__class__.__name__, arguments) - -class NodeEvent(Event): - def __init__(self, anchor, start_mark=None, end_mark=None): - self.anchor = anchor - self.start_mark = start_mark - self.end_mark = end_mark - -class CollectionStartEvent(NodeEvent): - def __init__(self, anchor, tag, implicit, start_mark=None, end_mark=None, - flow_style=None): - self.anchor = anchor - self.tag = tag - self.implicit = implicit - self.start_mark = start_mark - self.end_mark = end_mark - self.flow_style = flow_style - -class CollectionEndEvent(Event): - pass - -# Implementations. - -class StreamStartEvent(Event): - def __init__(self, start_mark=None, end_mark=None, encoding=None): - self.start_mark = start_mark - self.end_mark = end_mark - self.encoding = encoding - -class StreamEndEvent(Event): - pass - -class DocumentStartEvent(Event): - def __init__(self, start_mark=None, end_mark=None, - explicit=None, version=None, tags=None): - self.start_mark = start_mark - self.end_mark = end_mark - self.explicit = explicit - self.version = version - self.tags = tags - -class DocumentEndEvent(Event): - def __init__(self, start_mark=None, end_mark=None, - explicit=None): - self.start_mark = start_mark - self.end_mark = end_mark - self.explicit = explicit - -class AliasEvent(NodeEvent): - pass - -class ScalarEvent(NodeEvent): - def __init__(self, anchor, tag, implicit, value, - start_mark=None, end_mark=None, style=None): - self.anchor = anchor - self.tag = tag - self.implicit = implicit - self.value = value - self.start_mark = start_mark - self.end_mark = end_mark - self.style = style - -class SequenceStartEvent(CollectionStartEvent): - pass - -class SequenceEndEvent(CollectionEndEvent): - pass - -class MappingStartEvent(CollectionStartEvent): - pass - -class MappingEndEvent(CollectionEndEvent): - pass - diff --git a/plugins_available/util/yaml/loader.py b/plugins_available/util/yaml/loader.py deleted file mode 100644 index 293ff46..0000000 --- a/plugins_available/util/yaml/loader.py +++ /dev/null @@ -1,40 +0,0 @@ - -__all__ = ['BaseLoader', 'SafeLoader', 'Loader'] - -from reader import * -from scanner import * -from parser import * -from composer import * -from constructor import * -from resolver import * - -class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver): - - def __init__(self, stream): - Reader.__init__(self, stream) - Scanner.__init__(self) - Parser.__init__(self) - Composer.__init__(self) - BaseConstructor.__init__(self) - BaseResolver.__init__(self) - -class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver): - - def __init__(self, stream): - Reader.__init__(self, stream) - Scanner.__init__(self) - Parser.__init__(self) - Composer.__init__(self) - SafeConstructor.__init__(self) - Resolver.__init__(self) - -class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver): - - def __init__(self, stream): - Reader.__init__(self, stream) - Scanner.__init__(self) - Parser.__init__(self) - Composer.__init__(self) - Constructor.__init__(self) - Resolver.__init__(self) - diff --git a/plugins_available/util/yaml/nodes.py b/plugins_available/util/yaml/nodes.py deleted file mode 100644 index c4f070c..0000000 --- a/plugins_available/util/yaml/nodes.py +++ /dev/null @@ -1,49 +0,0 @@ - -class Node(object): - def __init__(self, tag, value, start_mark, end_mark): - self.tag = tag - self.value = value - self.start_mark = start_mark - self.end_mark = end_mark - def __repr__(self): - value = self.value - #if isinstance(value, list): - # if len(value) == 0: - # value = '' - # elif len(value) == 1: - # value = '<1 item>' - # else: - # value = '<%d items>' % len(value) - #else: - # if len(value) > 75: - # value = repr(value[:70]+u' ... ') - # else: - # value = repr(value) - value = repr(value) - return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value) - -class ScalarNode(Node): - id = 'scalar' - def __init__(self, tag, value, - start_mark=None, end_mark=None, style=None): - self.tag = tag - self.value = value - self.start_mark = start_mark - self.end_mark = end_mark - self.style = style - -class CollectionNode(Node): - def __init__(self, tag, value, - start_mark=None, end_mark=None, flow_style=None): - self.tag = tag - self.value = value - self.start_mark = start_mark - self.end_mark = end_mark - self.flow_style = flow_style - -class SequenceNode(CollectionNode): - id = 'sequence' - -class MappingNode(CollectionNode): - id = 'mapping' - diff --git a/plugins_available/util/yaml/parser.py b/plugins_available/util/yaml/parser.py deleted file mode 100644 index b6a7416..0000000 --- a/plugins_available/util/yaml/parser.py +++ /dev/null @@ -1,584 +0,0 @@ - -# The following YAML grammar is LL(1) and is parsed by a recursive descent -# parser. -# -# stream ::= STREAM-START implicit_document? explicit_document* STREAM-END -# implicit_document ::= block_node DOCUMENT-END* -# explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -# block_node_or_indentless_sequence ::= -# ALIAS -# | properties (block_content | indentless_block_sequence)? -# | block_content -# | indentless_block_sequence -# block_node ::= ALIAS -# | properties block_content? -# | block_content -# flow_node ::= ALIAS -# | properties flow_content? -# | flow_content -# properties ::= TAG ANCHOR? | ANCHOR TAG? -# block_content ::= block_collection | flow_collection | SCALAR -# flow_content ::= flow_collection | SCALAR -# block_collection ::= block_sequence | block_mapping -# flow_collection ::= flow_sequence | flow_mapping -# block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END -# indentless_sequence ::= (BLOCK-ENTRY block_node?)+ -# block_mapping ::= BLOCK-MAPPING_START -# ((KEY block_node_or_indentless_sequence?)? -# (VALUE block_node_or_indentless_sequence?)?)* -# BLOCK-END -# flow_sequence ::= FLOW-SEQUENCE-START -# (flow_sequence_entry FLOW-ENTRY)* -# flow_sequence_entry? -# FLOW-SEQUENCE-END -# flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -# flow_mapping ::= FLOW-MAPPING-START -# (flow_mapping_entry FLOW-ENTRY)* -# flow_mapping_entry? -# FLOW-MAPPING-END -# flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -# -# FIRST sets: -# -# stream: { STREAM-START } -# explicit_document: { DIRECTIVE DOCUMENT-START } -# implicit_document: FIRST(block_node) -# block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START } -# flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START } -# block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR } -# flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR } -# block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START } -# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START } -# block_sequence: { BLOCK-SEQUENCE-START } -# block_mapping: { BLOCK-MAPPING-START } -# block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START BLOCK-ENTRY } -# indentless_sequence: { ENTRY } -# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START } -# flow_sequence: { FLOW-SEQUENCE-START } -# flow_mapping: { FLOW-MAPPING-START } -# flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } -# flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } - -__all__ = ['Parser', 'ParserError'] - -from error import MarkedYAMLError -from tokens import * -from events import * -from scanner import * - -class ParserError(MarkedYAMLError): - pass - -class Parser(object): - # Since writing a recursive-descendant parser is a straightforward task, we - # do not give many comments here. - - DEFAULT_TAGS = { - u'!': u'!', - u'!!': u'tag:yaml.org,2002:', - } - - def __init__(self): - self.current_event = None - self.yaml_version = None - self.tag_handles = {} - self.states = [] - self.marks = [] - self.state = self.parse_stream_start - - def check_event(self, *choices): - # Check the type of the next event. - if self.current_event is None: - if self.state: - self.current_event = self.state() - if self.current_event is not None: - if not choices: - return True - for choice in choices: - if isinstance(self.current_event, choice): - return True - return False - - def peek_event(self): - # Get the next event. - if self.current_event is None: - if self.state: - self.current_event = self.state() - return self.current_event - - def get_event(self): - # Get the next event and proceed further. - if self.current_event is None: - if self.state: - self.current_event = self.state() - value = self.current_event - self.current_event = None - return value - - # stream ::= STREAM-START implicit_document? explicit_document* STREAM-END - # implicit_document ::= block_node DOCUMENT-END* - # explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* - - def parse_stream_start(self): - - # Parse the stream start. - token = self.get_token() - event = StreamStartEvent(token.start_mark, token.end_mark, - encoding=token.encoding) - - # Prepare the next state. - self.state = self.parse_implicit_document_start - - return event - - def parse_implicit_document_start(self): - - # Parse an implicit document. - if not self.check_token(DirectiveToken, DocumentStartToken, - StreamEndToken): - self.tag_handles = self.DEFAULT_TAGS - token = self.peek_token() - start_mark = end_mark = token.start_mark - event = DocumentStartEvent(start_mark, end_mark, - explicit=False) - - # Prepare the next state. - self.states.append(self.parse_document_end) - self.state = self.parse_block_node - - return event - - else: - return self.parse_document_start() - - def parse_document_start(self): - - # Parse any extra document end indicators. - while self.check_token(DocumentEndToken): - self.get_token() - - # Parse an explicit document. - if not self.check_token(StreamEndToken): - token = self.peek_token() - start_mark = token.start_mark - version, tags = self.process_directives() - if not self.check_token(DocumentStartToken): - raise ParserError(None, None, - "expected '', but found %r" - % self.peek_token().id, - self.peek_token().start_mark) - token = self.get_token() - end_mark = token.end_mark - event = DocumentStartEvent(start_mark, end_mark, - explicit=True, version=version, tags=tags) - self.states.append(self.parse_document_end) - self.state = self.parse_document_content - else: - # Parse the end of the stream. - token = self.get_token() - event = StreamEndEvent(token.start_mark, token.end_mark) - assert not self.states - assert not self.marks - self.state = None - return event - - def parse_document_end(self): - - # Parse the document end. - token = self.peek_token() - start_mark = end_mark = token.start_mark - explicit = False - if self.check_token(DocumentEndToken): - token = self.get_token() - end_mark = token.end_mark - explicit = True - event = DocumentEndEvent(start_mark, end_mark, - explicit=explicit) - - # Prepare the next state. - self.state = self.parse_document_start - - return event - - def parse_document_content(self): - if self.check_token(DirectiveToken, - DocumentStartToken, DocumentEndToken, StreamEndToken): - event = self.process_empty_scalar(self.peek_token().start_mark) - self.state = self.states.pop() - return event - else: - return self.parse_block_node() - - def process_directives(self): - self.yaml_version = None - self.tag_handles = {} - while self.check_token(DirectiveToken): - token = self.get_token() - if token.name == u'YAML': - if self.yaml_version is not None: - raise ParserError(None, None, - "found duplicate YAML directive", token.start_mark) - major, minor = token.value - if major != 1: - raise ParserError(None, None, - "found incompatible YAML document (version 1.* is required)", - token.start_mark) - self.yaml_version = token.value - elif token.name == u'TAG': - handle, prefix = token.value - if handle in self.tag_handles: - raise ParserError(None, None, - "duplicate tag handle %r" % handle.encode('utf-8'), - token.start_mark) - self.tag_handles[handle] = prefix - if self.tag_handles: - value = self.yaml_version, self.tag_handles.copy() - else: - value = self.yaml_version, None - for key in self.DEFAULT_TAGS: - if key not in self.tag_handles: - self.tag_handles[key] = self.DEFAULT_TAGS[key] - return value - - # block_node_or_indentless_sequence ::= ALIAS - # | properties (block_content | indentless_block_sequence)? - # | block_content - # | indentless_block_sequence - # block_node ::= ALIAS - # | properties block_content? - # | block_content - # flow_node ::= ALIAS - # | properties flow_content? - # | flow_content - # properties ::= TAG ANCHOR? | ANCHOR TAG? - # block_content ::= block_collection | flow_collection | SCALAR - # flow_content ::= flow_collection | SCALAR - # block_collection ::= block_sequence | block_mapping - # flow_collection ::= flow_sequence | flow_mapping - - def parse_block_node(self): - return self.parse_node(block=True) - - def parse_flow_node(self): - return self.parse_node() - - def parse_block_node_or_indentless_sequence(self): - return self.parse_node(block=True, indentless_sequence=True) - - def parse_node(self, block=False, indentless_sequence=False): - if self.check_token(AliasToken): - token = self.get_token() - event = AliasEvent(token.value, token.start_mark, token.end_mark) - self.state = self.states.pop() - else: - anchor = None - tag = None - start_mark = end_mark = tag_mark = None - if self.check_token(AnchorToken): - token = self.get_token() - start_mark = token.start_mark - end_mark = token.end_mark - anchor = token.value - if self.check_token(TagToken): - token = self.get_token() - tag_mark = token.start_mark - end_mark = token.end_mark - tag = token.value - elif self.check_token(TagToken): - token = self.get_token() - start_mark = tag_mark = token.start_mark - end_mark = token.end_mark - tag = token.value - if self.check_token(AnchorToken): - token = self.get_token() - end_mark = token.end_mark - anchor = token.value - if tag is not None: - handle, suffix = tag - if handle is not None: - if handle not in self.tag_handles: - raise ParserError("while parsing a node", start_mark, - "found undefined tag handle %r" % handle.encode('utf-8'), - tag_mark) - tag = self.tag_handles[handle]+suffix - else: - tag = suffix - #if tag == u'!': - # raise ParserError("while parsing a node", start_mark, - # "found non-specific tag '!'", tag_mark, - # "Please check 'http://pyyaml.org/wiki/YAMLNonSpecificTag' and share your opinion.") - if start_mark is None: - start_mark = end_mark = self.peek_token().start_mark - event = None - implicit = (tag is None or tag == u'!') - if indentless_sequence and self.check_token(BlockEntryToken): - end_mark = self.peek_token().end_mark - event = SequenceStartEvent(anchor, tag, implicit, - start_mark, end_mark) - self.state = self.parse_indentless_sequence_entry - else: - if self.check_token(ScalarToken): - token = self.get_token() - end_mark = token.end_mark - if (token.plain and tag is None) or tag == u'!': - implicit = (True, False) - elif tag is None: - implicit = (False, True) - else: - implicit = (False, False) - event = ScalarEvent(anchor, tag, implicit, token.value, - start_mark, end_mark, style=token.style) - self.state = self.states.pop() - elif self.check_token(FlowSequenceStartToken): - end_mark = self.peek_token().end_mark - event = SequenceStartEvent(anchor, tag, implicit, - start_mark, end_mark, flow_style=True) - self.state = self.parse_flow_sequence_first_entry - elif self.check_token(FlowMappingStartToken): - end_mark = self.peek_token().end_mark - event = MappingStartEvent(anchor, tag, implicit, - start_mark, end_mark, flow_style=True) - self.state = self.parse_flow_mapping_first_key - elif block and self.check_token(BlockSequenceStartToken): - end_mark = self.peek_token().start_mark - event = SequenceStartEvent(anchor, tag, implicit, - start_mark, end_mark, flow_style=False) - self.state = self.parse_block_sequence_first_entry - elif block and self.check_token(BlockMappingStartToken): - end_mark = self.peek_token().start_mark - event = MappingStartEvent(anchor, tag, implicit, - start_mark, end_mark, flow_style=False) - self.state = self.parse_block_mapping_first_key - elif anchor is not None or tag is not None: - # Empty scalars are allowed even if a tag or an anchor is - # specified. - event = ScalarEvent(anchor, tag, (implicit, False), u'', - start_mark, end_mark) - self.state = self.states.pop() - else: - if block: - node = 'block' - else: - node = 'flow' - token = self.peek_token() - raise ParserError("while parsing a %s node" % node, start_mark, - "expected the node content, but found %r" % token.id, - token.start_mark) - return event - - # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END - - def parse_block_sequence_first_entry(self): - token = self.get_token() - self.marks.append(token.start_mark) - return self.parse_block_sequence_entry() - - def parse_block_sequence_entry(self): - if self.check_token(BlockEntryToken): - token = self.get_token() - if not self.check_token(BlockEntryToken, BlockEndToken): - self.states.append(self.parse_block_sequence_entry) - return self.parse_block_node() - else: - self.state = self.parse_block_sequence_entry - return self.process_empty_scalar(token.end_mark) - if not self.check_token(BlockEndToken): - token = self.peek_token() - raise ParserError("while parsing a block collection", self.marks[-1], - "expected , but found %r" % token.id, token.start_mark) - token = self.get_token() - event = SequenceEndEvent(token.start_mark, token.end_mark) - self.state = self.states.pop() - self.marks.pop() - return event - - # indentless_sequence ::= (BLOCK-ENTRY block_node?)+ - - def parse_indentless_sequence_entry(self): - if self.check_token(BlockEntryToken): - token = self.get_token() - if not self.check_token(BlockEntryToken, - KeyToken, ValueToken, BlockEndToken): - self.states.append(self.parse_indentless_sequence_entry) - return self.parse_block_node() - else: - self.state = self.parse_indentless_sequence_entry - return self.process_empty_scalar(token.end_mark) - token = self.peek_token() - event = SequenceEndEvent(token.start_mark, token.start_mark) - self.state = self.states.pop() - return event - - # block_mapping ::= BLOCK-MAPPING_START - # ((KEY block_node_or_indentless_sequence?)? - # (VALUE block_node_or_indentless_sequence?)?)* - # BLOCK-END - - def parse_block_mapping_first_key(self): - token = self.get_token() - self.marks.append(token.start_mark) - return self.parse_block_mapping_key() - - def parse_block_mapping_key(self): - if self.check_token(KeyToken): - token = self.get_token() - if not self.check_token(KeyToken, ValueToken, BlockEndToken): - self.states.append(self.parse_block_mapping_value) - return self.parse_block_node_or_indentless_sequence() - else: - self.state = self.parse_block_mapping_value - return self.process_empty_scalar(token.end_mark) - if not self.check_token(BlockEndToken): - token = self.peek_token() - raise ParserError("while parsing a block mapping", self.marks[-1], - "expected , but found %r" % token.id, token.start_mark) - token = self.get_token() - event = MappingEndEvent(token.start_mark, token.end_mark) - self.state = self.states.pop() - self.marks.pop() - return event - - def parse_block_mapping_value(self): - if self.check_token(ValueToken): - token = self.get_token() - if not self.check_token(KeyToken, ValueToken, BlockEndToken): - self.states.append(self.parse_block_mapping_key) - return self.parse_block_node_or_indentless_sequence() - else: - self.state = self.parse_block_mapping_key - return self.process_empty_scalar(token.end_mark) - else: - self.state = self.parse_block_mapping_key - token = self.peek_token() - return self.process_empty_scalar(token.start_mark) - - # flow_sequence ::= FLOW-SEQUENCE-START - # (flow_sequence_entry FLOW-ENTRY)* - # flow_sequence_entry? - # FLOW-SEQUENCE-END - # flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - # - # Note that while production rules for both flow_sequence_entry and - # flow_mapping_entry are equal, their interpretations are different. - # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?` - # generate an inline mapping (set syntax). - - def parse_flow_sequence_first_entry(self): - token = self.get_token() - self.marks.append(token.start_mark) - return self.parse_flow_sequence_entry(first=True) - - def parse_flow_sequence_entry(self, first=False): - if not self.check_token(FlowSequenceEndToken): - if not first: - if self.check_token(FlowEntryToken): - self.get_token() - else: - token = self.peek_token() - raise ParserError("while parsing a flow sequence", self.marks[-1], - "expected ',' or ']', but got %r" % token.id, token.start_mark) - - if self.check_token(KeyToken): - token = self.peek_token() - event = MappingStartEvent(None, None, True, - token.start_mark, token.end_mark, - flow_style=True) - self.state = self.parse_flow_sequence_entry_mapping_key - return event - elif not self.check_token(FlowSequenceEndToken): - self.states.append(self.parse_flow_sequence_entry) - return self.parse_flow_node() - token = self.get_token() - event = SequenceEndEvent(token.start_mark, token.end_mark) - self.state = self.states.pop() - self.marks.pop() - return event - - def parse_flow_sequence_entry_mapping_key(self): - token = self.get_token() - if not self.check_token(ValueToken, - FlowEntryToken, FlowSequenceEndToken): - self.states.append(self.parse_flow_sequence_entry_mapping_value) - return self.parse_flow_node() - else: - self.state = self.parse_flow_sequence_entry_mapping_value - return self.process_empty_scalar(token.end_mark) - - def parse_flow_sequence_entry_mapping_value(self): - if self.check_token(ValueToken): - token = self.get_token() - if not self.check_token(FlowEntryToken, FlowSequenceEndToken): - self.states.append(self.parse_flow_sequence_entry_mapping_end) - return self.parse_flow_node() - else: - self.state = self.parse_flow_sequence_entry_mapping_end - return self.process_empty_scalar(token.end_mark) - else: - self.state = self.parse_flow_sequence_entry_mapping_end - token = self.peek_token() - return self.process_empty_scalar(token.start_mark) - - def parse_flow_sequence_entry_mapping_end(self): - self.state = self.parse_flow_sequence_entry - token = self.peek_token() - return MappingEndEvent(token.start_mark, token.start_mark) - - # flow_mapping ::= FLOW-MAPPING-START - # (flow_mapping_entry FLOW-ENTRY)* - # flow_mapping_entry? - # FLOW-MAPPING-END - # flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - - def parse_flow_mapping_first_key(self): - token = self.get_token() - self.marks.append(token.start_mark) - return self.parse_flow_mapping_key(first=True) - - def parse_flow_mapping_key(self, first=False): - if not self.check_token(FlowMappingEndToken): - if not first: - if self.check_token(FlowEntryToken): - self.get_token() - else: - token = self.peek_token() - raise ParserError("while parsing a flow mapping", self.marks[-1], - "expected ',' or '}', but got %r" % token.id, token.start_mark) - if self.check_token(KeyToken): - token = self.get_token() - if not self.check_token(ValueToken, - FlowEntryToken, FlowMappingEndToken): - self.states.append(self.parse_flow_mapping_value) - return self.parse_flow_node() - else: - self.state = self.parse_flow_mapping_value - return self.process_empty_scalar(token.end_mark) - elif not self.check_token(FlowMappingEndToken): - self.states.append(self.parse_flow_mapping_empty_value) - return self.parse_flow_node() - token = self.get_token() - event = MappingEndEvent(token.start_mark, token.end_mark) - self.state = self.states.pop() - self.marks.pop() - return event - - def parse_flow_mapping_value(self): - if self.check_token(ValueToken): - token = self.get_token() - if not self.check_token(FlowEntryToken, FlowMappingEndToken): - self.states.append(self.parse_flow_mapping_key) - return self.parse_flow_node() - else: - self.state = self.parse_flow_mapping_key - return self.process_empty_scalar(token.end_mark) - else: - self.state = self.parse_flow_mapping_key - token = self.peek_token() - return self.process_empty_scalar(token.start_mark) - - def parse_flow_mapping_empty_value(self): - self.state = self.parse_flow_mapping_key - return self.process_empty_scalar(self.peek_token().start_mark) - - def process_empty_scalar(self, mark): - return ScalarEvent(None, None, (True, False), u'', mark, mark) - diff --git a/plugins_available/util/yaml/reader.py b/plugins_available/util/yaml/reader.py deleted file mode 100644 index 1e7a4db..0000000 --- a/plugins_available/util/yaml/reader.py +++ /dev/null @@ -1,225 +0,0 @@ -# This module contains abstractions for the input stream. You don't have to -# looks further, there are no pretty code. -# -# We define two classes here. -# -# Mark(source, line, column) -# It's just a record and its only use is producing nice error messages. -# Parser does not use it for any other purposes. -# -# Reader(source, data) -# Reader determines the encoding of `data` and converts it to unicode. -# Reader provides the following methods and attributes: -# reader.peek(length=1) - return the next `length` characters -# reader.forward(length=1) - move the current position to `length` characters. -# reader.index - the number of the current character. -# reader.line, stream.column - the line and the column of the current character. - -__all__ = ['Reader', 'ReaderError'] - -from error import YAMLError, Mark - -import codecs, re - -# Unfortunately, codec functions in Python 2.3 does not support the `finish` -# arguments, so we have to write our own wrappers. - -try: - codecs.utf_8_decode('', 'strict', False) - from codecs import utf_8_decode, utf_16_le_decode, utf_16_be_decode - -except TypeError: - - def utf_16_le_decode(data, errors, finish=False): - if not finish and len(data) % 2 == 1: - data = data[:-1] - return codecs.utf_16_le_decode(data, errors) - - def utf_16_be_decode(data, errors, finish=False): - if not finish and len(data) % 2 == 1: - data = data[:-1] - return codecs.utf_16_be_decode(data, errors) - - def utf_8_decode(data, errors, finish=False): - if not finish: - # We are trying to remove a possible incomplete multibyte character - # from the suffix of the data. - # The first byte of a multi-byte sequence is in the range 0xc0 to 0xfd. - # All further bytes are in the range 0x80 to 0xbf. - # UTF-8 encoded UCS characters may be up to six bytes long. - count = 0 - while count < 5 and count < len(data) \ - and '\x80' <= data[-count-1] <= '\xBF': - count -= 1 - if count < 5 and count < len(data) \ - and '\xC0' <= data[-count-1] <= '\xFD': - data = data[:-count-1] - return codecs.utf_8_decode(data, errors) - -class ReaderError(YAMLError): - - def __init__(self, name, position, character, encoding, reason): - self.name = name - self.character = character - self.position = position - self.encoding = encoding - self.reason = reason - - def __str__(self): - if isinstance(self.character, str): - return "'%s' codec can't decode byte #x%02x: %s\n" \ - " in \"%s\", position %d" \ - % (self.encoding, ord(self.character), self.reason, - self.name, self.position) - else: - return "unacceptable character #x%04x: %s\n" \ - " in \"%s\", position %d" \ - % (self.character, self.reason, - self.name, self.position) - -class Reader(object): - # Reader: - # - determines the data encoding and converts it to unicode, - # - checks if characters are in allowed range, - # - adds '\0' to the end. - - # Reader accepts - # - a `str` object, - # - a `unicode` object, - # - a file-like object with its `read` method returning `str`, - # - a file-like object with its `read` method returning `unicode`. - - # Yeah, it's ugly and slow. - - def __init__(self, stream): - self.name = None - self.stream = None - self.stream_pointer = 0 - self.eof = True - self.buffer = u'' - self.pointer = 0 - self.raw_buffer = None - self.raw_decode = None - self.encoding = None - self.index = 0 - self.line = 0 - self.column = 0 - if isinstance(stream, unicode): - self.name = "" - self.check_printable(stream) - self.buffer = stream+u'\0' - elif isinstance(stream, str): - self.name = "" - self.raw_buffer = stream - self.determine_encoding() - else: - self.stream = stream - self.name = getattr(stream, 'name', "") - self.eof = False - self.raw_buffer = '' - self.determine_encoding() - - def peek(self, index=0): - try: - return self.buffer[self.pointer+index] - except IndexError: - self.update(index+1) - return self.buffer[self.pointer+index] - - def prefix(self, length=1): - if self.pointer+length >= len(self.buffer): - self.update(length) - return self.buffer[self.pointer:self.pointer+length] - - def forward(self, length=1): - if self.pointer+length+1 >= len(self.buffer): - self.update(length+1) - while length: - ch = self.buffer[self.pointer] - self.pointer += 1 - self.index += 1 - if ch in u'\n\x85\u2028\u2029' \ - or (ch == u'\r' and self.buffer[self.pointer] != u'\n'): - self.line += 1 - self.column = 0 - elif ch != u'\uFEFF': - self.column += 1 - length -= 1 - - def get_mark(self): - if self.stream is None: - return Mark(self.name, self.index, self.line, self.column, - self.buffer, self.pointer) - else: - return Mark(self.name, self.index, self.line, self.column, - None, None) - - def determine_encoding(self): - while not self.eof and len(self.raw_buffer) < 2: - self.update_raw() - if not isinstance(self.raw_buffer, unicode): - if self.raw_buffer.startswith(codecs.BOM_UTF16_LE): - self.raw_decode = utf_16_le_decode - self.encoding = 'utf-16-le' - elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE): - self.raw_decode = utf_16_be_decode - self.encoding = 'utf-16-be' - else: - self.raw_decode = utf_8_decode - self.encoding = 'utf-8' - self.update(1) - - NON_PRINTABLE = re.compile(u'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]') - def check_printable(self, data): - match = self.NON_PRINTABLE.search(data) - if match: - character = match.group() - position = self.index+(len(self.buffer)-self.pointer)+match.start() - raise ReaderError(self.name, position, ord(character), - 'unicode', "special characters are not allowed") - - def update(self, length): - if self.raw_buffer is None: - return - self.buffer = self.buffer[self.pointer:] - self.pointer = 0 - while len(self.buffer) < length: - if not self.eof: - self.update_raw() - if self.raw_decode is not None: - try: - data, converted = self.raw_decode(self.raw_buffer, - 'strict', self.eof) - except UnicodeDecodeError, exc: - character = exc.object[exc.start] - if self.stream is not None: - position = self.stream_pointer-len(self.raw_buffer)+exc.start - else: - position = exc.start - raise ReaderError(self.name, position, character, - exc.encoding, exc.reason) - else: - data = self.raw_buffer - converted = len(data) - self.check_printable(data) - self.buffer += data - self.raw_buffer = self.raw_buffer[converted:] - if self.eof: - self.buffer += u'\0' - self.raw_buffer = None - break - - def update_raw(self, size=1024): - data = self.stream.read(size) - if data: - self.raw_buffer += data - self.stream_pointer += len(data) - else: - self.eof = True - -#try: -# import psyco -# psyco.bind(Reader) -#except ImportError: -# pass - diff --git a/plugins_available/util/yaml/representer.py b/plugins_available/util/yaml/representer.py deleted file mode 100644 index f5606ec..0000000 --- a/plugins_available/util/yaml/representer.py +++ /dev/null @@ -1,489 +0,0 @@ - -__all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer', - 'RepresenterError'] - -from error import * -from nodes import * - -import datetime - -try: - set -except NameError: - from sets import Set as set - -import sys, copy_reg, types - -class RepresenterError(YAMLError): - pass - -class BaseRepresenter(object): - - yaml_representers = {} - yaml_multi_representers = {} - - def __init__(self, default_style=None, default_flow_style=None): - self.default_style = default_style - self.default_flow_style = default_flow_style - self.represented_objects = {} - self.object_keeper = [] - self.alias_key = None - - def represent(self, data): - node = self.represent_data(data) - self.serialize(node) - self.represented_objects = {} - self.object_keeper = [] - self.alias_key = None - - def get_classobj_bases(self, cls): - bases = [cls] - for base in cls.__bases__: - bases.extend(self.get_classobj_bases(base)) - return bases - - def represent_data(self, data): - if self.ignore_aliases(data): - self.alias_key = None - else: - self.alias_key = id(data) - if self.alias_key is not None: - if self.alias_key in self.represented_objects: - node = self.represented_objects[self.alias_key] - #if node is None: - # raise RepresenterError("recursive objects are not allowed: %r" % data) - return node - #self.represented_objects[alias_key] = None - self.object_keeper.append(data) - data_types = type(data).__mro__ - if type(data) is types.InstanceType: - data_types = self.get_classobj_bases(data.__class__)+list(data_types) - if data_types[0] in self.yaml_representers: - node = self.yaml_representers[data_types[0]](self, data) - else: - for data_type in data_types: - if data_type in self.yaml_multi_representers: - node = self.yaml_multi_representers[data_type](self, data) - break - else: - if None in self.yaml_multi_representers: - node = self.yaml_multi_representers[None](self, data) - elif None in self.yaml_representers: - node = self.yaml_representers[None](self, data) - else: - node = ScalarNode(None, unicode(data)) - #if alias_key is not None: - # self.represented_objects[alias_key] = node - return node - - def add_representer(cls, data_type, representer): - if not 'yaml_representers' in cls.__dict__: - cls.yaml_representers = cls.yaml_representers.copy() - cls.yaml_representers[data_type] = representer - add_representer = classmethod(add_representer) - - def add_multi_representer(cls, data_type, representer): - if not 'yaml_multi_representers' in cls.__dict__: - cls.yaml_multi_representers = cls.yaml_multi_representers.copy() - cls.yaml_multi_representers[data_type] = representer - add_multi_representer = classmethod(add_multi_representer) - - def represent_scalar(self, tag, value, style=None): - if style is None: - style = self.default_style - node = ScalarNode(tag, value, style=style) - if self.alias_key is not None: - self.represented_objects[self.alias_key] = node - return node - - def represent_sequence(self, tag, sequence, flow_style=None): - value = [] - node = SequenceNode(tag, value, flow_style=flow_style) - if self.alias_key is not None: - self.represented_objects[self.alias_key] = node - best_style = True - for item in sequence: - node_item = self.represent_data(item) - if not (isinstance(node_item, ScalarNode) and not node_item.style): - best_style = False - value.append(node_item) - if flow_style is None: - if self.default_flow_style is not None: - node.flow_style = self.default_flow_style - else: - node.flow_style = best_style - return node - - def represent_mapping(self, tag, mapping, flow_style=None): - value = [] - node = MappingNode(tag, value, flow_style=flow_style) - if self.alias_key is not None: - self.represented_objects[self.alias_key] = node - best_style = True - if hasattr(mapping, 'items'): - mapping = mapping.items() - mapping.sort() - for item_key, item_value in mapping: - node_key = self.represent_data(item_key) - node_value = self.represent_data(item_value) - if not (isinstance(node_key, ScalarNode) and not node_key.style): - best_style = False - if not (isinstance(node_value, ScalarNode) and not node_value.style): - best_style = False - value.append((node_key, node_value)) - if flow_style is None: - if self.default_flow_style is not None: - node.flow_style = self.default_flow_style - else: - node.flow_style = best_style - return node - - def ignore_aliases(self, data): - return False - -class SafeRepresenter(BaseRepresenter): - - def ignore_aliases(self, data): - if data in [None, ()]: - return True - if isinstance(data, (str, unicode, bool, int, float)): - return True - - def represent_none(self, data): - return self.represent_scalar(u'tag:yaml.org,2002:null', - u'null') - - def represent_str(self, data): - tag = None - style = None - try: - data = unicode(data, 'ascii') - tag = u'tag:yaml.org,2002:str' - except UnicodeDecodeError: - try: - data = unicode(data, 'utf-8') - tag = u'tag:yaml.org,2002:str' - except UnicodeDecodeError: - data = data.encode('base64') - tag = u'tag:yaml.org,2002:binary' - style = '|' - return self.represent_scalar(tag, data, style=style) - - def represent_unicode(self, data): - return self.represent_scalar(u'tag:yaml.org,2002:str', data) - - def represent_bool(self, data): - if data: - value = u'true' - else: - value = u'false' - return self.represent_scalar(u'tag:yaml.org,2002:bool', value) - - def represent_int(self, data): - return self.represent_scalar(u'tag:yaml.org,2002:int', unicode(data)) - - def represent_long(self, data): - return self.represent_scalar(u'tag:yaml.org,2002:int', unicode(data)) - - inf_value = 1e300 - while repr(inf_value) != repr(inf_value*inf_value): - inf_value *= inf_value - - def represent_float(self, data): - if data != data or (data == 0.0 and data == 1.0): - value = u'.nan' - elif data == self.inf_value: - value = u'.inf' - elif data == -self.inf_value: - value = u'-.inf' - else: - value = unicode(repr(data)).lower() - # Note that in some cases `repr(data)` represents a float number - # without the decimal parts. For instance: - # >>> repr(1e17) - # '1e17' - # Unfortunately, this is not a valid float representation according - # to the definition of the `!!float` tag. We fix this by adding - # '.0' before the 'e' symbol. - if u'.' not in value and u'e' in value: - value = value.replace(u'e', u'.0e', 1) - return self.represent_scalar(u'tag:yaml.org,2002:float', value) - - def represent_list(self, data): - #pairs = (len(data) > 0 and isinstance(data, list)) - #if pairs: - # for item in data: - # if not isinstance(item, tuple) or len(item) != 2: - # pairs = False - # break - #if not pairs: - return self.represent_sequence(u'tag:yaml.org,2002:seq', data) - #value = [] - #for item_key, item_value in data: - # value.append(self.represent_mapping(u'tag:yaml.org,2002:map', - # [(item_key, item_value)])) - #return SequenceNode(u'tag:yaml.org,2002:pairs', value) - - def represent_dict(self, data): - return self.represent_mapping(u'tag:yaml.org,2002:map', data) - - def represent_set(self, data): - value = {} - for key in data: - value[key] = None - return self.represent_mapping(u'tag:yaml.org,2002:set', value) - - def represent_date(self, data): - value = unicode(data.isoformat()) - return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value) - - def represent_datetime(self, data): - value = unicode(data.isoformat(' ')) - return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value) - - def represent_yaml_object(self, tag, data, cls, flow_style=None): - if hasattr(data, '__getstate__'): - state = data.__getstate__() - else: - state = data.__dict__.copy() - return self.represent_mapping(tag, state, flow_style=flow_style) - - def represent_undefined(self, data): - raise RepresenterError("cannot represent an object: %s" % data) - -SafeRepresenter.add_representer(type(None), - SafeRepresenter.represent_none) - -SafeRepresenter.add_representer(str, - SafeRepresenter.represent_str) - -SafeRepresenter.add_representer(unicode, - SafeRepresenter.represent_unicode) - -SafeRepresenter.add_representer(bool, - SafeRepresenter.represent_bool) - -SafeRepresenter.add_representer(int, - SafeRepresenter.represent_int) - -SafeRepresenter.add_representer(long, - SafeRepresenter.represent_long) - -SafeRepresenter.add_representer(float, - SafeRepresenter.represent_float) - -SafeRepresenter.add_representer(list, - SafeRepresenter.represent_list) - -SafeRepresenter.add_representer(tuple, - SafeRepresenter.represent_list) - -SafeRepresenter.add_representer(dict, - SafeRepresenter.represent_dict) - -SafeRepresenter.add_representer(set, - SafeRepresenter.represent_set) - -SafeRepresenter.add_representer(datetime.date, - SafeRepresenter.represent_date) - -SafeRepresenter.add_representer(datetime.datetime, - SafeRepresenter.represent_datetime) - -SafeRepresenter.add_representer(None, - SafeRepresenter.represent_undefined) - -class Representer(SafeRepresenter): - - def represent_str(self, data): - tag = None - style = None - try: - data = unicode(data, 'ascii') - tag = u'tag:yaml.org,2002:str' - except UnicodeDecodeError: - try: - data = unicode(data, 'utf-8') - tag = u'tag:yaml.org,2002:python/str' - except UnicodeDecodeError: - data = data.encode('base64') - tag = u'tag:yaml.org,2002:binary' - style = '|' - return self.represent_scalar(tag, data, style=style) - - def represent_unicode(self, data): - tag = None - try: - data.encode('ascii') - tag = u'tag:yaml.org,2002:python/unicode' - except UnicodeEncodeError: - tag = u'tag:yaml.org,2002:str' - return self.represent_scalar(tag, data) - - def represent_long(self, data): - tag = u'tag:yaml.org,2002:int' - if int(data) is not data: - tag = u'tag:yaml.org,2002:python/long' - return self.represent_scalar(tag, unicode(data)) - - def represent_complex(self, data): - if data.imag == 0.0: - data = u'%r' % data.real - elif data.real == 0.0: - data = u'%rj' % data.imag - elif data.imag > 0: - data = u'%r+%rj' % (data.real, data.imag) - else: - data = u'%r%rj' % (data.real, data.imag) - return self.represent_scalar(u'tag:yaml.org,2002:python/complex', data) - - def represent_tuple(self, data): - return self.represent_sequence(u'tag:yaml.org,2002:python/tuple', data) - - def represent_name(self, data): - name = u'%s.%s' % (data.__module__, data.__name__) - return self.represent_scalar(u'tag:yaml.org,2002:python/name:'+name, u'') - - def represent_module(self, data): - return self.represent_scalar( - u'tag:yaml.org,2002:python/module:'+data.__name__, u'') - - def represent_instance(self, data): - # For instances of classic classes, we use __getinitargs__ and - # __getstate__ to serialize the data. - - # If data.__getinitargs__ exists, the object must be reconstructed by - # calling cls(**args), where args is a tuple returned by - # __getinitargs__. Otherwise, the cls.__init__ method should never be - # called and the class instance is created by instantiating a trivial - # class and assigning to the instance's __class__ variable. - - # If data.__getstate__ exists, it returns the state of the object. - # Otherwise, the state of the object is data.__dict__. - - # We produce either a !!python/object or !!python/object/new node. - # If data.__getinitargs__ does not exist and state is a dictionary, we - # produce a !!python/object node . Otherwise we produce a - # !!python/object/new node. - - cls = data.__class__ - class_name = u'%s.%s' % (cls.__module__, cls.__name__) - args = None - state = None - if hasattr(data, '__getinitargs__'): - args = list(data.__getinitargs__()) - if hasattr(data, '__getstate__'): - state = data.__getstate__() - else: - state = data.__dict__ - if args is None and isinstance(state, dict): - return self.represent_mapping( - u'tag:yaml.org,2002:python/object:'+class_name, state) - if isinstance(state, dict) and not state: - return self.represent_sequence( - u'tag:yaml.org,2002:python/object/new:'+class_name, args) - value = {} - if args: - value['args'] = args - value['state'] = state - return self.represent_mapping( - u'tag:yaml.org,2002:python/object/new:'+class_name, value) - - def represent_object(self, data): - # We use __reduce__ API to save the data. data.__reduce__ returns - # a tuple of length 2-5: - # (function, args, state, listitems, dictitems) - - # For reconstructing, we calls function(*args), then set its state, - # listitems, and dictitems if they are not None. - - # A special case is when function.__name__ == '__newobj__'. In this - # case we create the object with args[0].__new__(*args). - - # Another special case is when __reduce__ returns a string - we don't - # support it. - - # We produce a !!python/object, !!python/object/new or - # !!python/object/apply node. - - cls = type(data) - if cls in copy_reg.dispatch_table: - reduce = copy_reg.dispatch_table[cls](data) - elif hasattr(data, '__reduce_ex__'): - reduce = data.__reduce_ex__(2) - elif hasattr(data, '__reduce__'): - reduce = data.__reduce__() - else: - raise RepresenterError("cannot represent object: %r" % data) - reduce = (list(reduce)+[None]*5)[:5] - function, args, state, listitems, dictitems = reduce - args = list(args) - if state is None: - state = {} - if listitems is not None: - listitems = list(listitems) - if dictitems is not None: - dictitems = dict(dictitems) - if function.__name__ == '__newobj__': - function = args[0] - args = args[1:] - tag = u'tag:yaml.org,2002:python/object/new:' - newobj = True - else: - tag = u'tag:yaml.org,2002:python/object/apply:' - newobj = False - function_name = u'%s.%s' % (function.__module__, function.__name__) - if not args and not listitems and not dictitems \ - and isinstance(state, dict) and newobj: - return self.represent_mapping( - u'tag:yaml.org,2002:python/object:'+function_name, state) - if not listitems and not dictitems \ - and isinstance(state, dict) and not state: - return self.represent_sequence(tag+function_name, args) - value = {} - if args: - value['args'] = args - if state or not isinstance(state, dict): - value['state'] = state - if listitems: - value['listitems'] = listitems - if dictitems: - value['dictitems'] = dictitems - return self.represent_mapping(tag+function_name, value) - -Representer.add_representer(str, - Representer.represent_str) - -Representer.add_representer(unicode, - Representer.represent_unicode) - -Representer.add_representer(long, - Representer.represent_long) - -Representer.add_representer(complex, - Representer.represent_complex) - -Representer.add_representer(tuple, - Representer.represent_tuple) - -Representer.add_representer(type, - Representer.represent_name) - -Representer.add_representer(types.ClassType, - Representer.represent_name) - -Representer.add_representer(types.FunctionType, - Representer.represent_name) - -Representer.add_representer(types.BuiltinFunctionType, - Representer.represent_name) - -Representer.add_representer(types.ModuleType, - Representer.represent_module) - -Representer.add_multi_representer(types.InstanceType, - Representer.represent_instance) - -Representer.add_multi_representer(object, - Representer.represent_object) - diff --git a/plugins_available/util/yaml/resolver.py b/plugins_available/util/yaml/resolver.py deleted file mode 100644 index 6b5ab87..0000000 --- a/plugins_available/util/yaml/resolver.py +++ /dev/null @@ -1,224 +0,0 @@ - -__all__ = ['BaseResolver', 'Resolver'] - -from error import * -from nodes import * - -import re - -class ResolverError(YAMLError): - pass - -class BaseResolver(object): - - DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str' - DEFAULT_SEQUENCE_TAG = u'tag:yaml.org,2002:seq' - DEFAULT_MAPPING_TAG = u'tag:yaml.org,2002:map' - - yaml_implicit_resolvers = {} - yaml_path_resolvers = {} - - def __init__(self): - self.resolver_exact_paths = [] - self.resolver_prefix_paths = [] - - def add_implicit_resolver(cls, tag, regexp, first): - if not 'yaml_implicit_resolvers' in cls.__dict__: - cls.yaml_implicit_resolvers = cls.yaml_implicit_resolvers.copy() - if first is None: - first = [None] - for ch in first: - cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp)) - add_implicit_resolver = classmethod(add_implicit_resolver) - - def add_path_resolver(cls, tag, path, kind=None): - # Note: `add_path_resolver` is experimental. The API could be changed. - # `new_path` is a pattern that is matched against the path from the - # root to the node that is being considered. `node_path` elements are - # tuples `(node_check, index_check)`. `node_check` is a node class: - # `ScalarNode`, `SequenceNode`, `MappingNode` or `None`. `None` - # matches any kind of a node. `index_check` could be `None`, a boolean - # value, a string value, or a number. `None` and `False` match against - # any _value_ of sequence and mapping nodes. `True` matches against - # any _key_ of a mapping node. A string `index_check` matches against - # a mapping value that corresponds to a scalar key which content is - # equal to the `index_check` value. An integer `index_check` matches - # against a sequence value with the index equal to `index_check`. - if not 'yaml_path_resolvers' in cls.__dict__: - cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy() - new_path = [] - for element in path: - if isinstance(element, (list, tuple)): - if len(element) == 2: - node_check, index_check = element - elif len(element) == 1: - node_check = element[0] - index_check = True - else: - raise ResolverError("Invalid path element: %s" % element) - else: - node_check = None - index_check = element - if node_check is str: - node_check = ScalarNode - elif node_check is list: - node_check = SequenceNode - elif node_check is dict: - node_check = MappingNode - elif node_check not in [ScalarNode, SequenceNode, MappingNode] \ - and not isinstance(node_check, basestring) \ - and node_check is not None: - raise ResolverError("Invalid node checker: %s" % node_check) - if not isinstance(index_check, (basestring, int)) \ - and index_check is not None: - raise ResolverError("Invalid index checker: %s" % index_check) - new_path.append((node_check, index_check)) - if kind is str: - kind = ScalarNode - elif kind is list: - kind = SequenceNode - elif kind is dict: - kind = MappingNode - elif kind not in [ScalarNode, SequenceNode, MappingNode] \ - and kind is not None: - raise ResolverError("Invalid node kind: %s" % kind) - cls.yaml_path_resolvers[tuple(new_path), kind] = tag - add_path_resolver = classmethod(add_path_resolver) - - def descend_resolver(self, current_node, current_index): - if not self.yaml_path_resolvers: - return - exact_paths = {} - prefix_paths = [] - if current_node: - depth = len(self.resolver_prefix_paths) - for path, kind in self.resolver_prefix_paths[-1]: - if self.check_resolver_prefix(depth, path, kind, - current_node, current_index): - if len(path) > depth: - prefix_paths.append((path, kind)) - else: - exact_paths[kind] = self.yaml_path_resolvers[path, kind] - else: - for path, kind in self.yaml_path_resolvers: - if not path: - exact_paths[kind] = self.yaml_path_resolvers[path, kind] - else: - prefix_paths.append((path, kind)) - self.resolver_exact_paths.append(exact_paths) - self.resolver_prefix_paths.append(prefix_paths) - - def ascend_resolver(self): - if not self.yaml_path_resolvers: - return - self.resolver_exact_paths.pop() - self.resolver_prefix_paths.pop() - - def check_resolver_prefix(self, depth, path, kind, - current_node, current_index): - node_check, index_check = path[depth-1] - if isinstance(node_check, basestring): - if current_node.tag != node_check: - return - elif node_check is not None: - if not isinstance(current_node, node_check): - return - if index_check is True and current_index is not None: - return - if (index_check is False or index_check is None) \ - and current_index is None: - return - if isinstance(index_check, basestring): - if not (isinstance(current_index, ScalarNode) - and index_check == current_index.value): - return - elif isinstance(index_check, int) and not isinstance(index_check, bool): - if index_check != current_index: - return - return True - - def resolve(self, kind, value, implicit): - if kind is ScalarNode and implicit[0]: - if value == u'': - resolvers = self.yaml_implicit_resolvers.get(u'', []) - else: - resolvers = self.yaml_implicit_resolvers.get(value[0], []) - resolvers += self.yaml_implicit_resolvers.get(None, []) - for tag, regexp in resolvers: - if regexp.match(value): - return tag - implicit = implicit[1] - if self.yaml_path_resolvers: - exact_paths = self.resolver_exact_paths[-1] - if kind in exact_paths: - return exact_paths[kind] - if None in exact_paths: - return exact_paths[None] - if kind is ScalarNode: - return self.DEFAULT_SCALAR_TAG - elif kind is SequenceNode: - return self.DEFAULT_SEQUENCE_TAG - elif kind is MappingNode: - return self.DEFAULT_MAPPING_TAG - -class Resolver(BaseResolver): - pass - -Resolver.add_implicit_resolver( - u'tag:yaml.org,2002:bool', - re.compile(ur'''^(?:yes|Yes|YES|no|No|NO - |true|True|TRUE|false|False|FALSE - |on|On|ON|off|Off|OFF)$''', re.X), - list(u'yYnNtTfFoO')) - -Resolver.add_implicit_resolver( - u'tag:yaml.org,2002:float', - re.compile(ur'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)? - |\.[0-9_]+(?:[eE][-+][0-9]+)? - |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]* - |[-+]?\.(?:inf|Inf|INF) - |\.(?:nan|NaN|NAN))$''', re.X), - list(u'-+0123456789.')) - -Resolver.add_implicit_resolver( - u'tag:yaml.org,2002:int', - re.compile(ur'''^(?:[-+]?0b[0-1_]+ - |[-+]?0[0-7_]+ - |[-+]?(?:0|[1-9][0-9_]*) - |[-+]?0x[0-9a-fA-F_]+ - |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X), - list(u'-+0123456789')) - -Resolver.add_implicit_resolver( - u'tag:yaml.org,2002:merge', - re.compile(ur'^(?:<<)$'), - [u'<']) - -Resolver.add_implicit_resolver( - u'tag:yaml.org,2002:null', - re.compile(ur'''^(?: ~ - |null|Null|NULL - | )$''', re.X), - [u'~', u'n', u'N', u'']) - -Resolver.add_implicit_resolver( - u'tag:yaml.org,2002:timestamp', - re.compile(ur'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] - |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]? - (?:[Tt]|[ \t]+)[0-9][0-9]? - :[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)? - (?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X), - list(u'0123456789')) - -Resolver.add_implicit_resolver( - u'tag:yaml.org,2002:value', - re.compile(ur'^(?:=)$'), - [u'=']) - -# The following resolver is only for documentation purposes. It cannot work -# because plain scalars cannot start with '!', '&', or '*'. -Resolver.add_implicit_resolver( - u'tag:yaml.org,2002:yaml', - re.compile(ur'^(?:!|&|\*)$'), - list(u'!&*')) - diff --git a/plugins_available/util/yaml/scanner.py b/plugins_available/util/yaml/scanner.py deleted file mode 100644 index 5228fad..0000000 --- a/plugins_available/util/yaml/scanner.py +++ /dev/null @@ -1,1457 +0,0 @@ - -# Scanner produces tokens of the following types: -# STREAM-START -# STREAM-END -# DIRECTIVE(name, value) -# DOCUMENT-START -# DOCUMENT-END -# BLOCK-SEQUENCE-START -# BLOCK-MAPPING-START -# BLOCK-END -# FLOW-SEQUENCE-START -# FLOW-MAPPING-START -# FLOW-SEQUENCE-END -# FLOW-MAPPING-END -# BLOCK-ENTRY -# FLOW-ENTRY -# KEY -# VALUE -# ALIAS(value) -# ANCHOR(value) -# TAG(value) -# SCALAR(value, plain, style) -# -# Read comments in the Scanner code for more details. -# - -__all__ = ['Scanner', 'ScannerError'] - -from error import MarkedYAMLError -from tokens import * - -class ScannerError(MarkedYAMLError): - pass - -class SimpleKey(object): - # See below simple keys treatment. - - def __init__(self, token_number, required, index, line, column, mark): - self.token_number = token_number - self.required = required - self.index = index - self.line = line - self.column = column - self.mark = mark - -class Scanner(object): - - def __init__(self): - """Initialize the scanner.""" - # It is assumed that Scanner and Reader will have a common descendant. - # Reader do the dirty work of checking for BOM and converting the - # input data to Unicode. It also adds NUL to the end. - # - # Reader supports the following methods - # self.peek(i=0) # peek the next i-th character - # self.prefix(l=1) # peek the next l characters - # self.forward(l=1) # read the next l characters and move the pointer. - - # Had we reached the end of the stream? - self.done = False - - # The number of unclosed '{' and '['. `flow_level == 0` means block - # context. - self.flow_level = 0 - - # List of processed tokens that are not yet emitted. - self.tokens = [] - - # Add the STREAM-START token. - self.fetch_stream_start() - - # Number of tokens that were emitted through the `get_token` method. - self.tokens_taken = 0 - - # The current indentation level. - self.indent = -1 - - # Past indentation levels. - self.indents = [] - - # Variables related to simple keys treatment. - - # A simple key is a key that is not denoted by the '?' indicator. - # Example of simple keys: - # --- - # block simple key: value - # ? not a simple key: - # : { flow simple key: value } - # We emit the KEY token before all keys, so when we find a potential - # simple key, we try to locate the corresponding ':' indicator. - # Simple keys should be limited to a single line and 1024 characters. - - # Can a simple key start at the current position? A simple key may - # start: - # - at the beginning of the line, not counting indentation spaces - # (in block context), - # - after '{', '[', ',' (in the flow context), - # - after '?', ':', '-' (in the block context). - # In the block context, this flag also signifies if a block collection - # may start at the current position. - self.allow_simple_key = True - - # Keep track of possible simple keys. This is a dictionary. The key - # is `flow_level`; there can be no more that one possible simple key - # for each level. The value is a SimpleKey record: - # (token_number, required, index, line, column, mark) - # A simple key may start with ALIAS, ANCHOR, TAG, SCALAR(flow), - # '[', or '{' tokens. - self.possible_simple_keys = {} - - # Public methods. - - def check_token(self, *choices): - # Check if the next token is one of the given types. - while self.need_more_tokens(): - self.fetch_more_tokens() - if self.tokens: - if not choices: - return True - for choice in choices: - if isinstance(self.tokens[0], choice): - return True - return False - - def peek_token(self): - # Return the next token, but do not delete if from the queue. - while self.need_more_tokens(): - self.fetch_more_tokens() - if self.tokens: - return self.tokens[0] - - def get_token(self): - # Return the next token. - while self.need_more_tokens(): - self.fetch_more_tokens() - if self.tokens: - self.tokens_taken += 1 - return self.tokens.pop(0) - - # Private methods. - - def need_more_tokens(self): - if self.done: - return False - if not self.tokens: - return True - # The current token may be a potential simple key, so we - # need to look further. - self.stale_possible_simple_keys() - if self.next_possible_simple_key() == self.tokens_taken: - return True - - def fetch_more_tokens(self): - - # Eat whitespaces and comments until we reach the next token. - self.scan_to_next_token() - - # Remove obsolete possible simple keys. - self.stale_possible_simple_keys() - - # Compare the current indentation and column. It may add some tokens - # and decrease the current indentation level. - self.unwind_indent(self.column) - - # Peek the next character. - ch = self.peek() - - # Is it the end of stream? - if ch == u'\0': - return self.fetch_stream_end() - - # Is it a directive? - if ch == u'%' and self.check_directive(): - return self.fetch_directive() - - # Is it the document start? - if ch == u'-' and self.check_document_start(): - return self.fetch_document_start() - - # Is it the document end? - if ch == u'.' and self.check_document_end(): - return self.fetch_document_end() - - # TODO: support for BOM within a stream. - #if ch == u'\uFEFF': - # return self.fetch_bom() <-- issue BOMToken - - # Note: the order of the following checks is NOT significant. - - # Is it the flow sequence start indicator? - if ch == u'[': - return self.fetch_flow_sequence_start() - - # Is it the flow mapping start indicator? - if ch == u'{': - return self.fetch_flow_mapping_start() - - # Is it the flow sequence end indicator? - if ch == u']': - return self.fetch_flow_sequence_end() - - # Is it the flow mapping end indicator? - if ch == u'}': - return self.fetch_flow_mapping_end() - - # Is it the flow entry indicator? - if ch == u',': - return self.fetch_flow_entry() - - # Is it the block entry indicator? - if ch == u'-' and self.check_block_entry(): - return self.fetch_block_entry() - - # Is it the key indicator? - if ch == u'?' and self.check_key(): - return self.fetch_key() - - # Is it the value indicator? - if ch == u':' and self.check_value(): - return self.fetch_value() - - # Is it an alias? - if ch == u'*': - return self.fetch_alias() - - # Is it an anchor? - if ch == u'&': - return self.fetch_anchor() - - # Is it a tag? - if ch == u'!': - return self.fetch_tag() - - # Is it a literal scalar? - if ch == u'|' and not self.flow_level: - return self.fetch_literal() - - # Is it a folded scalar? - if ch == u'>' and not self.flow_level: - return self.fetch_folded() - - # Is it a single quoted scalar? - if ch == u'\'': - return self.fetch_single() - - # Is it a double quoted scalar? - if ch == u'\"': - return self.fetch_double() - - # It must be a plain scalar then. - if self.check_plain(): - return self.fetch_plain() - - # No? It's an error. Let's produce a nice error message. - raise ScannerError("while scanning for the next token", None, - "found character %r that cannot start any token" - % ch.encode('utf-8'), self.get_mark()) - - # Simple keys treatment. - - def next_possible_simple_key(self): - # Return the number of the nearest possible simple key. Actually we - # don't need to loop through the whole dictionary. We may replace it - # with the following code: - # if not self.possible_simple_keys: - # return None - # return self.possible_simple_keys[ - # min(self.possible_simple_keys.keys())].token_number - min_token_number = None - for level in self.possible_simple_keys: - key = self.possible_simple_keys[level] - if min_token_number is None or key.token_number < min_token_number: - min_token_number = key.token_number - return min_token_number - - def stale_possible_simple_keys(self): - # Remove entries that are no longer possible simple keys. According to - # the YAML specification, simple keys - # - should be limited to a single line, - # - should be no longer than 1024 characters. - # Disabling this procedure will allow simple keys of any length and - # height (may cause problems if indentation is broken though). - for level in self.possible_simple_keys.keys(): - key = self.possible_simple_keys[level] - if key.line != self.line \ - or self.index-key.index > 1024: - if key.required: - raise ScannerError("while scanning a simple key", key.mark, - "could not found expected ':'", self.get_mark()) - del self.possible_simple_keys[level] - - def save_possible_simple_key(self): - # The next token may start a simple key. We check if it's possible - # and save its position. This function is called for - # ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'. - - # Check if a simple key is required at the current position. - required = not self.flow_level and self.indent == self.column - - # A simple key is required only if it is the first token in the current - # line. Therefore it is always allowed. - assert self.allow_simple_key or not required - - # The next token might be a simple key. Let's save it's number and - # position. - if self.allow_simple_key: - self.remove_possible_simple_key() - token_number = self.tokens_taken+len(self.tokens) - key = SimpleKey(token_number, required, - self.index, self.line, self.column, self.get_mark()) - self.possible_simple_keys[self.flow_level] = key - - def remove_possible_simple_key(self): - # Remove the saved possible key position at the current flow level. - if self.flow_level in self.possible_simple_keys: - key = self.possible_simple_keys[self.flow_level] - - if key.required: - raise ScannerError("while scanning a simple key", key.mark, - "could not found expected ':'", self.get_mark()) - - del self.possible_simple_keys[self.flow_level] - - # Indentation functions. - - def unwind_indent(self, column): - - ## In flow context, tokens should respect indentation. - ## Actually the condition should be `self.indent >= column` according to - ## the spec. But this condition will prohibit intuitively correct - ## constructions such as - ## key : { - ## } - #if self.flow_level and self.indent > column: - # raise ScannerError(None, None, - # "invalid intendation or unclosed '[' or '{'", - # self.get_mark()) - - # In the flow context, indentation is ignored. We make the scanner less - # restrictive then specification requires. - if self.flow_level: - return - - # In block context, we may need to issue the BLOCK-END tokens. - while self.indent > column: - mark = self.get_mark() - self.indent = self.indents.pop() - self.tokens.append(BlockEndToken(mark, mark)) - - def add_indent(self, column): - # Check if we need to increase indentation. - if self.indent < column: - self.indents.append(self.indent) - self.indent = column - return True - return False - - # Fetchers. - - def fetch_stream_start(self): - # We always add STREAM-START as the first token and STREAM-END as the - # last token. - - # Read the token. - mark = self.get_mark() - - # Add STREAM-START. - self.tokens.append(StreamStartToken(mark, mark, - encoding=self.encoding)) - - - def fetch_stream_end(self): - - # Set the current intendation to -1. - self.unwind_indent(-1) - - # Reset simple keys. - self.remove_possible_simple_key() - self.allow_simple_key = False - self.possible_simple_keys = {} - - # Read the token. - mark = self.get_mark() - - # Add STREAM-END. - self.tokens.append(StreamEndToken(mark, mark)) - - # The steam is finished. - self.done = True - - def fetch_directive(self): - - # Set the current intendation to -1. - self.unwind_indent(-1) - - # Reset simple keys. - self.remove_possible_simple_key() - self.allow_simple_key = False - - # Scan and add DIRECTIVE. - self.tokens.append(self.scan_directive()) - - def fetch_document_start(self): - self.fetch_document_indicator(DocumentStartToken) - - def fetch_document_end(self): - self.fetch_document_indicator(DocumentEndToken) - - def fetch_document_indicator(self, TokenClass): - - # Set the current intendation to -1. - self.unwind_indent(-1) - - # Reset simple keys. Note that there could not be a block collection - # after '---'. - self.remove_possible_simple_key() - self.allow_simple_key = False - - # Add DOCUMENT-START or DOCUMENT-END. - start_mark = self.get_mark() - self.forward(3) - end_mark = self.get_mark() - self.tokens.append(TokenClass(start_mark, end_mark)) - - def fetch_flow_sequence_start(self): - self.fetch_flow_collection_start(FlowSequenceStartToken) - - def fetch_flow_mapping_start(self): - self.fetch_flow_collection_start(FlowMappingStartToken) - - def fetch_flow_collection_start(self, TokenClass): - - # '[' and '{' may start a simple key. - self.save_possible_simple_key() - - # Increase the flow level. - self.flow_level += 1 - - # Simple keys are allowed after '[' and '{'. - self.allow_simple_key = True - - # Add FLOW-SEQUENCE-START or FLOW-MAPPING-START. - start_mark = self.get_mark() - self.forward() - end_mark = self.get_mark() - self.tokens.append(TokenClass(start_mark, end_mark)) - - def fetch_flow_sequence_end(self): - self.fetch_flow_collection_end(FlowSequenceEndToken) - - def fetch_flow_mapping_end(self): - self.fetch_flow_collection_end(FlowMappingEndToken) - - def fetch_flow_collection_end(self, TokenClass): - - # Reset possible simple key on the current level. - self.remove_possible_simple_key() - - # Decrease the flow level. - self.flow_level -= 1 - - # No simple keys after ']' or '}'. - self.allow_simple_key = False - - # Add FLOW-SEQUENCE-END or FLOW-MAPPING-END. - start_mark = self.get_mark() - self.forward() - end_mark = self.get_mark() - self.tokens.append(TokenClass(start_mark, end_mark)) - - def fetch_flow_entry(self): - - # Simple keys are allowed after ','. - self.allow_simple_key = True - - # Reset possible simple key on the current level. - self.remove_possible_simple_key() - - # Add FLOW-ENTRY. - start_mark = self.get_mark() - self.forward() - end_mark = self.get_mark() - self.tokens.append(FlowEntryToken(start_mark, end_mark)) - - def fetch_block_entry(self): - - # Block context needs additional checks. - if not self.flow_level: - - # Are we allowed to start a new entry? - if not self.allow_simple_key: - raise ScannerError(None, None, - "sequence entries are not allowed here", - self.get_mark()) - - # We may need to add BLOCK-SEQUENCE-START. - if self.add_indent(self.column): - mark = self.get_mark() - self.tokens.append(BlockSequenceStartToken(mark, mark)) - - # It's an error for the block entry to occur in the flow context, - # but we let the parser detect this. - else: - pass - - # Simple keys are allowed after '-'. - self.allow_simple_key = True - - # Reset possible simple key on the current level. - self.remove_possible_simple_key() - - # Add BLOCK-ENTRY. - start_mark = self.get_mark() - self.forward() - end_mark = self.get_mark() - self.tokens.append(BlockEntryToken(start_mark, end_mark)) - - def fetch_key(self): - - # Block context needs additional checks. - if not self.flow_level: - - # Are we allowed to start a key (not nessesary a simple)? - if not self.allow_simple_key: - raise ScannerError(None, None, - "mapping keys are not allowed here", - self.get_mark()) - - # We may need to add BLOCK-MAPPING-START. - if self.add_indent(self.column): - mark = self.get_mark() - self.tokens.append(BlockMappingStartToken(mark, mark)) - - # Simple keys are allowed after '?' in the block context. - self.allow_simple_key = not self.flow_level - - # Reset possible simple key on the current level. - self.remove_possible_simple_key() - - # Add KEY. - start_mark = self.get_mark() - self.forward() - end_mark = self.get_mark() - self.tokens.append(KeyToken(start_mark, end_mark)) - - def fetch_value(self): - - # Do we determine a simple key? - if self.flow_level in self.possible_simple_keys: - - # Add KEY. - key = self.possible_simple_keys[self.flow_level] - del self.possible_simple_keys[self.flow_level] - self.tokens.insert(key.token_number-self.tokens_taken, - KeyToken(key.mark, key.mark)) - - # If this key starts a new block mapping, we need to add - # BLOCK-MAPPING-START. - if not self.flow_level: - if self.add_indent(key.column): - self.tokens.insert(key.token_number-self.tokens_taken, - BlockMappingStartToken(key.mark, key.mark)) - - # There cannot be two simple keys one after another. - self.allow_simple_key = False - - # It must be a part of a complex key. - else: - - # Block context needs additional checks. - # (Do we really need them? They will be catched by the parser - # anyway.) - if not self.flow_level: - - # We are allowed to start a complex value if and only if - # we can start a simple key. - if not self.allow_simple_key: - raise ScannerError(None, None, - "mapping values are not allowed here", - self.get_mark()) - - # If this value starts a new block mapping, we need to add - # BLOCK-MAPPING-START. It will be detected as an error later by - # the parser. - if not self.flow_level: - if self.add_indent(self.column): - mark = self.get_mark() - self.tokens.append(BlockMappingStartToken(mark, mark)) - - # Simple keys are allowed after ':' in the block context. - self.allow_simple_key = not self.flow_level - - # Reset possible simple key on the current level. - self.remove_possible_simple_key() - - # Add VALUE. - start_mark = self.get_mark() - self.forward() - end_mark = self.get_mark() - self.tokens.append(ValueToken(start_mark, end_mark)) - - def fetch_alias(self): - - # ALIAS could be a simple key. - self.save_possible_simple_key() - - # No simple keys after ALIAS. - self.allow_simple_key = False - - # Scan and add ALIAS. - self.tokens.append(self.scan_anchor(AliasToken)) - - def fetch_anchor(self): - - # ANCHOR could start a simple key. - self.save_possible_simple_key() - - # No simple keys after ANCHOR. - self.allow_simple_key = False - - # Scan and add ANCHOR. - self.tokens.append(self.scan_anchor(AnchorToken)) - - def fetch_tag(self): - - # TAG could start a simple key. - self.save_possible_simple_key() - - # No simple keys after TAG. - self.allow_simple_key = False - - # Scan and add TAG. - self.tokens.append(self.scan_tag()) - - def fetch_literal(self): - self.fetch_block_scalar(style='|') - - def fetch_folded(self): - self.fetch_block_scalar(style='>') - - def fetch_block_scalar(self, style): - - # A simple key may follow a block scalar. - self.allow_simple_key = True - - # Reset possible simple key on the current level. - self.remove_possible_simple_key() - - # Scan and add SCALAR. - self.tokens.append(self.scan_block_scalar(style)) - - def fetch_single(self): - self.fetch_flow_scalar(style='\'') - - def fetch_double(self): - self.fetch_flow_scalar(style='"') - - def fetch_flow_scalar(self, style): - - # A flow scalar could be a simple key. - self.save_possible_simple_key() - - # No simple keys after flow scalars. - self.allow_simple_key = False - - # Scan and add SCALAR. - self.tokens.append(self.scan_flow_scalar(style)) - - def fetch_plain(self): - - # A plain scalar could be a simple key. - self.save_possible_simple_key() - - # No simple keys after plain scalars. But note that `scan_plain` will - # change this flag if the scan is finished at the beginning of the - # line. - self.allow_simple_key = False - - # Scan and add SCALAR. May change `allow_simple_key`. - self.tokens.append(self.scan_plain()) - - # Checkers. - - def check_directive(self): - - # DIRECTIVE: ^ '%' ... - # The '%' indicator is already checked. - if self.column == 0: - return True - - def check_document_start(self): - - # DOCUMENT-START: ^ '---' (' '|'\n') - if self.column == 0: - if self.prefix(3) == u'---' \ - and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029': - return True - - def check_document_end(self): - - # DOCUMENT-END: ^ '...' (' '|'\n') - if self.column == 0: - if self.prefix(3) == u'...' \ - and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029': - return True - - def check_block_entry(self): - - # BLOCK-ENTRY: '-' (' '|'\n') - return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029' - - def check_key(self): - - # KEY(flow context): '?' - if self.flow_level: - return True - - # KEY(block context): '?' (' '|'\n') - else: - return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029' - - def check_value(self): - - # VALUE(flow context): ':' - if self.flow_level: - return True - - # VALUE(block context): ':' (' '|'\n') - else: - return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029' - - def check_plain(self): - - # A plain scalar may start with any non-space character except: - # '-', '?', ':', ',', '[', ']', '{', '}', - # '#', '&', '*', '!', '|', '>', '\'', '\"', - # '%', '@', '`'. - # - # It may also start with - # '-', '?', ':' - # if it is followed by a non-space character. - # - # Note that we limit the last rule to the block context (except the - # '-' character) because we want the flow context to be space - # independent. - ch = self.peek() - return ch not in u'\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`' \ - or (self.peek(1) not in u'\0 \t\r\n\x85\u2028\u2029' - and (ch == u'-' or (not self.flow_level and ch in u'?:'))) - - # Scanners. - - def scan_to_next_token(self): - # We ignore spaces, line breaks and comments. - # If we find a line break in the block context, we set the flag - # `allow_simple_key` on. - # The byte order mark is stripped if it's the first character in the - # stream. We do not yet support BOM inside the stream as the - # specification requires. Any such mark will be considered as a part - # of the document. - # - # TODO: We need to make tab handling rules more sane. A good rule is - # Tabs cannot precede tokens - # BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END, - # KEY(block), VALUE(block), BLOCK-ENTRY - # So the checking code is - # if : - # self.allow_simple_keys = False - # We also need to add the check for `allow_simple_keys == True` to - # `unwind_indent` before issuing BLOCK-END. - # Scanners for block, flow, and plain scalars need to be modified. - - if self.index == 0 and self.peek() == u'\uFEFF': - self.forward() - found = False - while not found: - while self.peek() == u' ': - self.forward() - if self.peek() == u'#': - while self.peek() not in u'\0\r\n\x85\u2028\u2029': - self.forward() - if self.scan_line_break(): - if not self.flow_level: - self.allow_simple_key = True - else: - found = True - - def scan_directive(self): - # See the specification for details. - start_mark = self.get_mark() - self.forward() - name = self.scan_directive_name(start_mark) - value = None - if name == u'YAML': - value = self.scan_yaml_directive_value(start_mark) - end_mark = self.get_mark() - elif name == u'TAG': - value = self.scan_tag_directive_value(start_mark) - end_mark = self.get_mark() - else: - end_mark = self.get_mark() - while self.peek() not in u'\0\r\n\x85\u2028\u2029': - self.forward() - self.scan_directive_ignored_line(start_mark) - return DirectiveToken(name, value, start_mark, end_mark) - - def scan_directive_name(self, start_mark): - # See the specification for details. - length = 0 - ch = self.peek(length) - while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ - or ch in u'-_': - length += 1 - ch = self.peek(length) - if not length: - raise ScannerError("while scanning a directive", start_mark, - "expected alphabetic or numeric character, but found %r" - % ch.encode('utf-8'), self.get_mark()) - value = self.prefix(length) - self.forward(length) - ch = self.peek() - if ch not in u'\0 \r\n\x85\u2028\u2029': - raise ScannerError("while scanning a directive", start_mark, - "expected alphabetic or numeric character, but found %r" - % ch.encode('utf-8'), self.get_mark()) - return value - - def scan_yaml_directive_value(self, start_mark): - # See the specification for details. - while self.peek() == u' ': - self.forward() - major = self.scan_yaml_directive_number(start_mark) - if self.peek() != '.': - raise ScannerError("while scanning a directive", start_mark, - "expected a digit or '.', but found %r" - % self.peek().encode('utf-8'), - self.get_mark()) - self.forward() - minor = self.scan_yaml_directive_number(start_mark) - if self.peek() not in u'\0 \r\n\x85\u2028\u2029': - raise ScannerError("while scanning a directive", start_mark, - "expected a digit or ' ', but found %r" - % self.peek().encode('utf-8'), - self.get_mark()) - return (major, minor) - - def scan_yaml_directive_number(self, start_mark): - # See the specification for details. - ch = self.peek() - if not (u'0' <= ch <= u'9'): - raise ScannerError("while scanning a directive", start_mark, - "expected a digit, but found %r" % ch.encode('utf-8'), - self.get_mark()) - length = 0 - while u'0' <= self.peek(length) <= u'9': - length += 1 - value = int(self.prefix(length)) - self.forward(length) - return value - - def scan_tag_directive_value(self, start_mark): - # See the specification for details. - while self.peek() == u' ': - self.forward() - handle = self.scan_tag_directive_handle(start_mark) - while self.peek() == u' ': - self.forward() - prefix = self.scan_tag_directive_prefix(start_mark) - return (handle, prefix) - - def scan_tag_directive_handle(self, start_mark): - # See the specification for details. - value = self.scan_tag_handle('directive', start_mark) - ch = self.peek() - if ch != u' ': - raise ScannerError("while scanning a directive", start_mark, - "expected ' ', but found %r" % ch.encode('utf-8'), - self.get_mark()) - return value - - def scan_tag_directive_prefix(self, start_mark): - # See the specification for details. - value = self.scan_tag_uri('directive', start_mark) - ch = self.peek() - if ch not in u'\0 \r\n\x85\u2028\u2029': - raise ScannerError("while scanning a directive", start_mark, - "expected ' ', but found %r" % ch.encode('utf-8'), - self.get_mark()) - return value - - def scan_directive_ignored_line(self, start_mark): - # See the specification for details. - while self.peek() == u' ': - self.forward() - if self.peek() == u'#': - while self.peek() not in u'\0\r\n\x85\u2028\u2029': - self.forward() - ch = self.peek() - if ch not in u'\0\r\n\x85\u2028\u2029': - raise ScannerError("while scanning a directive", start_mark, - "expected a comment or a line break, but found %r" - % ch.encode('utf-8'), self.get_mark()) - self.scan_line_break() - - def scan_anchor(self, TokenClass): - # The specification does not restrict characters for anchors and - # aliases. This may lead to problems, for instance, the document: - # [ *alias, value ] - # can be interpteted in two ways, as - # [ "value" ] - # and - # [ *alias , "value" ] - # Therefore we restrict aliases to numbers and ASCII letters. - start_mark = self.get_mark() - indicator = self.peek() - if indicator == u'*': - name = 'alias' - else: - name = 'anchor' - self.forward() - length = 0 - ch = self.peek(length) - while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ - or ch in u'-_': - length += 1 - ch = self.peek(length) - if not length: - raise ScannerError("while scanning an %s" % name, start_mark, - "expected alphabetic or numeric character, but found %r" - % ch.encode('utf-8'), self.get_mark()) - value = self.prefix(length) - self.forward(length) - ch = self.peek() - if ch not in u'\0 \t\r\n\x85\u2028\u2029?:,]}%@`': - raise ScannerError("while scanning an %s" % name, start_mark, - "expected alphabetic or numeric character, but found %r" - % ch.encode('utf-8'), self.get_mark()) - end_mark = self.get_mark() - return TokenClass(value, start_mark, end_mark) - - def scan_tag(self): - # See the specification for details. - start_mark = self.get_mark() - ch = self.peek(1) - if ch == u'<': - handle = None - self.forward(2) - suffix = self.scan_tag_uri('tag', start_mark) - if self.peek() != u'>': - raise ScannerError("while parsing a tag", start_mark, - "expected '>', but found %r" % self.peek().encode('utf-8'), - self.get_mark()) - self.forward() - elif ch in u'\0 \t\r\n\x85\u2028\u2029': - handle = None - suffix = u'!' - self.forward() - else: - length = 1 - use_handle = False - while ch not in u'\0 \r\n\x85\u2028\u2029': - if ch == u'!': - use_handle = True - break - length += 1 - ch = self.peek(length) - handle = u'!' - if use_handle: - handle = self.scan_tag_handle('tag', start_mark) - else: - handle = u'!' - self.forward() - suffix = self.scan_tag_uri('tag', start_mark) - ch = self.peek() - if ch not in u'\0 \r\n\x85\u2028\u2029': - raise ScannerError("while scanning a tag", start_mark, - "expected ' ', but found %r" % ch.encode('utf-8'), - self.get_mark()) - value = (handle, suffix) - end_mark = self.get_mark() - return TagToken(value, start_mark, end_mark) - - def scan_block_scalar(self, style): - # See the specification for details. - - if style == '>': - folded = True - else: - folded = False - - chunks = [] - start_mark = self.get_mark() - - # Scan the header. - self.forward() - chomping, increment = self.scan_block_scalar_indicators(start_mark) - self.scan_block_scalar_ignored_line(start_mark) - - # Determine the indentation level and go to the first non-empty line. - min_indent = self.indent+1 - if min_indent < 1: - min_indent = 1 - if increment is None: - breaks, max_indent, end_mark = self.scan_block_scalar_indentation() - indent = max(min_indent, max_indent) - else: - indent = min_indent+increment-1 - breaks, end_mark = self.scan_block_scalar_breaks(indent) - line_break = u'' - - # Scan the inner part of the block scalar. - while self.column == indent and self.peek() != u'\0': - chunks.extend(breaks) - leading_non_space = self.peek() not in u' \t' - length = 0 - while self.peek(length) not in u'\0\r\n\x85\u2028\u2029': - length += 1 - chunks.append(self.prefix(length)) - self.forward(length) - line_break = self.scan_line_break() - breaks, end_mark = self.scan_block_scalar_breaks(indent) - if self.column == indent and self.peek() != u'\0': - - # Unfortunately, folding rules are ambiguous. - # - # This is the folding according to the specification: - - if folded and line_break == u'\n' \ - and leading_non_space and self.peek() not in u' \t': - if not breaks: - chunks.append(u' ') - else: - chunks.append(line_break) - - # This is Clark Evans's interpretation (also in the spec - # examples): - # - #if folded and line_break == u'\n': - # if not breaks: - # if self.peek() not in ' \t': - # chunks.append(u' ') - # else: - # chunks.append(line_break) - #else: - # chunks.append(line_break) - else: - break - - # Chomp the tail. - if chomping is not False: - chunks.append(line_break) - if chomping is True: - chunks.extend(breaks) - - # We are done. - return ScalarToken(u''.join(chunks), False, start_mark, end_mark, - style) - - def scan_block_scalar_indicators(self, start_mark): - # See the specification for details. - chomping = None - increment = None - ch = self.peek() - if ch in u'+-': - if ch == '+': - chomping = True - else: - chomping = False - self.forward() - ch = self.peek() - if ch in u'0123456789': - increment = int(ch) - if increment == 0: - raise ScannerError("while scanning a block scalar", start_mark, - "expected indentation indicator in the range 1-9, but found 0", - self.get_mark()) - self.forward() - elif ch in u'0123456789': - increment = int(ch) - if increment == 0: - raise ScannerError("while scanning a block scalar", start_mark, - "expected indentation indicator in the range 1-9, but found 0", - self.get_mark()) - self.forward() - ch = self.peek() - if ch in u'+-': - if ch == '+': - chomping = True - else: - chomping = False - self.forward() - ch = self.peek() - if ch not in u'\0 \r\n\x85\u2028\u2029': - raise ScannerError("while scanning a block scalar", start_mark, - "expected chomping or indentation indicators, but found %r" - % ch.encode('utf-8'), self.get_mark()) - return chomping, increment - - def scan_block_scalar_ignored_line(self, start_mark): - # See the specification for details. - while self.peek() == u' ': - self.forward() - if self.peek() == u'#': - while self.peek() not in u'\0\r\n\x85\u2028\u2029': - self.forward() - ch = self.peek() - if ch not in u'\0\r\n\x85\u2028\u2029': - raise ScannerError("while scanning a block scalar", start_mark, - "expected a comment or a line break, but found %r" - % ch.encode('utf-8'), self.get_mark()) - self.scan_line_break() - - def scan_block_scalar_indentation(self): - # See the specification for details. - chunks = [] - max_indent = 0 - end_mark = self.get_mark() - while self.peek() in u' \r\n\x85\u2028\u2029': - if self.peek() != u' ': - chunks.append(self.scan_line_break()) - end_mark = self.get_mark() - else: - self.forward() - if self.column > max_indent: - max_indent = self.column - return chunks, max_indent, end_mark - - def scan_block_scalar_breaks(self, indent): - # See the specification for details. - chunks = [] - end_mark = self.get_mark() - while self.column < indent and self.peek() == u' ': - self.forward() - while self.peek() in u'\r\n\x85\u2028\u2029': - chunks.append(self.scan_line_break()) - end_mark = self.get_mark() - while self.column < indent and self.peek() == u' ': - self.forward() - return chunks, end_mark - - def scan_flow_scalar(self, style): - # See the specification for details. - # Note that we loose indentation rules for quoted scalars. Quoted - # scalars don't need to adhere indentation because " and ' clearly - # mark the beginning and the end of them. Therefore we are less - # restrictive then the specification requires. We only need to check - # that document separators are not included in scalars. - if style == '"': - double = True - else: - double = False - chunks = [] - start_mark = self.get_mark() - quote = self.peek() - self.forward() - chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark)) - while self.peek() != quote: - chunks.extend(self.scan_flow_scalar_spaces(double, start_mark)) - chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark)) - self.forward() - end_mark = self.get_mark() - return ScalarToken(u''.join(chunks), False, start_mark, end_mark, - style) - - ESCAPE_REPLACEMENTS = { - u'0': u'\0', - u'a': u'\x07', - u'b': u'\x08', - u't': u'\x09', - u'\t': u'\x09', - u'n': u'\x0A', - u'v': u'\x0B', - u'f': u'\x0C', - u'r': u'\x0D', - u'e': u'\x1B', - u' ': u'\x20', - u'\"': u'\"', - u'\\': u'\\', - u'N': u'\x85', - u'_': u'\xA0', - u'L': u'\u2028', - u'P': u'\u2029', - } - - ESCAPE_CODES = { - u'x': 2, - u'u': 4, - u'U': 8, - } - - def scan_flow_scalar_non_spaces(self, double, start_mark): - # See the specification for details. - chunks = [] - while True: - length = 0 - while self.peek(length) not in u'\'\"\\\0 \t\r\n\x85\u2028\u2029': - length += 1 - if length: - chunks.append(self.prefix(length)) - self.forward(length) - ch = self.peek() - if not double and ch == u'\'' and self.peek(1) == u'\'': - chunks.append(u'\'') - self.forward(2) - elif (double and ch == u'\'') or (not double and ch in u'\"\\'): - chunks.append(ch) - self.forward() - elif double and ch == u'\\': - self.forward() - ch = self.peek() - if ch in self.ESCAPE_REPLACEMENTS: - chunks.append(self.ESCAPE_REPLACEMENTS[ch]) - self.forward() - elif ch in self.ESCAPE_CODES: - length = self.ESCAPE_CODES[ch] - self.forward() - for k in range(length): - if self.peek(k) not in u'0123456789ABCDEFabcdef': - raise ScannerError("while scanning a double-quoted scalar", start_mark, - "expected escape sequence of %d hexdecimal numbers, but found %r" % - (length, self.peek(k).encode('utf-8')), self.get_mark()) - code = int(self.prefix(length), 16) - chunks.append(unichr(code)) - self.forward(length) - elif ch in u'\r\n\x85\u2028\u2029': - self.scan_line_break() - chunks.extend(self.scan_flow_scalar_breaks(double, start_mark)) - else: - raise ScannerError("while scanning a double-quoted scalar", start_mark, - "found unknown escape character %r" % ch.encode('utf-8'), self.get_mark()) - else: - return chunks - - def scan_flow_scalar_spaces(self, double, start_mark): - # See the specification for details. - chunks = [] - length = 0 - while self.peek(length) in u' \t': - length += 1 - whitespaces = self.prefix(length) - self.forward(length) - ch = self.peek() - if ch == u'\0': - raise ScannerError("while scanning a quoted scalar", start_mark, - "found unexpected end of stream", self.get_mark()) - elif ch in u'\r\n\x85\u2028\u2029': - line_break = self.scan_line_break() - breaks = self.scan_flow_scalar_breaks(double, start_mark) - if line_break != u'\n': - chunks.append(line_break) - elif not breaks: - chunks.append(u' ') - chunks.extend(breaks) - else: - chunks.append(whitespaces) - return chunks - - def scan_flow_scalar_breaks(self, double, start_mark): - # See the specification for details. - chunks = [] - while True: - # Instead of checking indentation, we check for document - # separators. - prefix = self.prefix(3) - if (prefix == u'---' or prefix == u'...') \ - and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029': - raise ScannerError("while scanning a quoted scalar", start_mark, - "found unexpected document separator", self.get_mark()) - while self.peek() in u' \t': - self.forward() - if self.peek() in u'\r\n\x85\u2028\u2029': - chunks.append(self.scan_line_break()) - else: - return chunks - - def scan_plain(self): - # See the specification for details. - # We add an additional restriction for the flow context: - # plain scalars in the flow context cannot contain ',', ':' and '?'. - # We also keep track of the `allow_simple_key` flag here. - # Indentation rules are loosed for the flow context. - chunks = [] - start_mark = self.get_mark() - end_mark = start_mark - indent = self.indent+1 - # We allow zero indentation for scalars, but then we need to check for - # document separators at the beginning of the line. - #if indent == 0: - # indent = 1 - spaces = [] - while True: - length = 0 - if self.peek() == u'#': - break - while True: - ch = self.peek(length) - if ch in u'\0 \t\r\n\x85\u2028\u2029' \ - or (not self.flow_level and ch == u':' and - self.peek(length+1) in u'\0 \t\r\n\x85\u2028\u2029') \ - or (self.flow_level and ch in u',:?[]{}'): - break - length += 1 - # It's not clear what we should do with ':' in the flow context. - if (self.flow_level and ch == u':' - and self.peek(length+1) not in u'\0 \t\r\n\x85\u2028\u2029,[]{}'): - self.forward(length) - raise ScannerError("while scanning a plain scalar", start_mark, - "found unexpected ':'", self.get_mark(), - "Please check http://pyyaml.org/wiki/YAMLColonInFlowContext for details.") - if length == 0: - break - self.allow_simple_key = False - chunks.extend(spaces) - chunks.append(self.prefix(length)) - self.forward(length) - end_mark = self.get_mark() - spaces = self.scan_plain_spaces(indent, start_mark) - if not spaces or self.peek() == u'#' \ - or (not self.flow_level and self.column < indent): - break - return ScalarToken(u''.join(chunks), True, start_mark, end_mark) - - def scan_plain_spaces(self, indent, start_mark): - # See the specification for details. - # The specification is really confusing about tabs in plain scalars. - # We just forbid them completely. Do not use tabs in YAML! - chunks = [] - length = 0 - while self.peek(length) in u' ': - length += 1 - whitespaces = self.prefix(length) - self.forward(length) - ch = self.peek() - if ch in u'\r\n\x85\u2028\u2029': - line_break = self.scan_line_break() - self.allow_simple_key = True - prefix = self.prefix(3) - if (prefix == u'---' or prefix == u'...') \ - and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029': - return - breaks = [] - while self.peek() in u' \r\n\x85\u2028\u2029': - if self.peek() == ' ': - self.forward() - else: - breaks.append(self.scan_line_break()) - prefix = self.prefix(3) - if (prefix == u'---' or prefix == u'...') \ - and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029': - return - if line_break != u'\n': - chunks.append(line_break) - elif not breaks: - chunks.append(u' ') - chunks.extend(breaks) - elif whitespaces: - chunks.append(whitespaces) - return chunks - - def scan_tag_handle(self, name, start_mark): - # See the specification for details. - # For some strange reasons, the specification does not allow '_' in - # tag handles. I have allowed it anyway. - ch = self.peek() - if ch != u'!': - raise ScannerError("while scanning a %s" % name, start_mark, - "expected '!', but found %r" % ch.encode('utf-8'), - self.get_mark()) - length = 1 - ch = self.peek(length) - if ch != u' ': - while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ - or ch in u'-_': - length += 1 - ch = self.peek(length) - if ch != u'!': - self.forward(length) - raise ScannerError("while scanning a %s" % name, start_mark, - "expected '!', but found %r" % ch.encode('utf-8'), - self.get_mark()) - length += 1 - value = self.prefix(length) - self.forward(length) - return value - - def scan_tag_uri(self, name, start_mark): - # See the specification for details. - # Note: we do not check if URI is well-formed. - chunks = [] - length = 0 - ch = self.peek(length) - while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ - or ch in u'-;/?:@&=+$,_.!~*\'()[]%': - if ch == u'%': - chunks.append(self.prefix(length)) - self.forward(length) - length = 0 - chunks.append(self.scan_uri_escapes(name, start_mark)) - else: - length += 1 - ch = self.peek(length) - if length: - chunks.append(self.prefix(length)) - self.forward(length) - length = 0 - if not chunks: - raise ScannerError("while parsing a %s" % name, start_mark, - "expected URI, but found %r" % ch.encode('utf-8'), - self.get_mark()) - return u''.join(chunks) - - def scan_uri_escapes(self, name, start_mark): - # See the specification for details. - bytes = [] - mark = self.get_mark() - while self.peek() == u'%': - self.forward() - for k in range(2): - if self.peek(k) not in u'0123456789ABCDEFabcdef': - raise ScannerError("while scanning a %s" % name, start_mark, - "expected URI escape sequence of 2 hexdecimal numbers, but found %r" % - (self.peek(k).encode('utf-8')), self.get_mark()) - bytes.append(chr(int(self.prefix(2), 16))) - self.forward(2) - try: - value = unicode(''.join(bytes), 'utf-8') - except UnicodeDecodeError, exc: - raise ScannerError("while scanning a %s" % name, start_mark, str(exc), mark) - return value - - def scan_line_break(self): - # Transforms: - # '\r\n' : '\n' - # '\r' : '\n' - # '\n' : '\n' - # '\x85' : '\n' - # '\u2028' : '\u2028' - # '\u2029 : '\u2029' - # default : '' - ch = self.peek() - if ch in u'\r\n\x85': - if self.prefix(2) == u'\r\n': - self.forward(2) - else: - self.forward() - return u'\n' - elif ch in u'\u2028\u2029': - self.forward() - return ch - return u'' - -#try: -# import psyco -# psyco.bind(Scanner) -#except ImportError: -# pass - diff --git a/plugins_available/util/yaml/serializer.py b/plugins_available/util/yaml/serializer.py deleted file mode 100644 index 0bf1e96..0000000 --- a/plugins_available/util/yaml/serializer.py +++ /dev/null @@ -1,111 +0,0 @@ - -__all__ = ['Serializer', 'SerializerError'] - -from error import YAMLError -from events import * -from nodes import * - -class SerializerError(YAMLError): - pass - -class Serializer(object): - - ANCHOR_TEMPLATE = u'id%03d' - - def __init__(self, encoding=None, - explicit_start=None, explicit_end=None, version=None, tags=None): - self.use_encoding = encoding - self.use_explicit_start = explicit_start - self.use_explicit_end = explicit_end - self.use_version = version - self.use_tags = tags - self.serialized_nodes = {} - self.anchors = {} - self.last_anchor_id = 0 - self.closed = None - - def open(self): - if self.closed is None: - self.emit(StreamStartEvent(encoding=self.use_encoding)) - self.closed = False - elif self.closed: - raise SerializerError("serializer is closed") - else: - raise SerializerError("serializer is already opened") - - def close(self): - if self.closed is None: - raise SerializerError("serializer is not opened") - elif not self.closed: - self.emit(StreamEndEvent()) - self.closed = True - - #def __del__(self): - # self.close() - - def serialize(self, node): - if self.closed is None: - raise SerializerError("serializer is not opened") - elif self.closed: - raise SerializerError("serializer is closed") - self.emit(DocumentStartEvent(explicit=self.use_explicit_start, - version=self.use_version, tags=self.use_tags)) - self.anchor_node(node) - self.serialize_node(node, None, None) - self.emit(DocumentEndEvent(explicit=self.use_explicit_end)) - self.serialized_nodes = {} - self.anchors = {} - self.last_anchor_id = 0 - - def anchor_node(self, node): - if node in self.anchors: - if self.anchors[node] is None: - self.anchors[node] = self.generate_anchor(node) - else: - self.anchors[node] = None - if isinstance(node, SequenceNode): - for item in node.value: - self.anchor_node(item) - elif isinstance(node, MappingNode): - for key, value in node.value: - self.anchor_node(key) - self.anchor_node(value) - - def generate_anchor(self, node): - self.last_anchor_id += 1 - return self.ANCHOR_TEMPLATE % self.last_anchor_id - - def serialize_node(self, node, parent, index): - alias = self.anchors[node] - if node in self.serialized_nodes: - self.emit(AliasEvent(alias)) - else: - self.serialized_nodes[node] = True - self.descend_resolver(parent, index) - if isinstance(node, ScalarNode): - detected_tag = self.resolve(ScalarNode, node.value, (True, False)) - default_tag = self.resolve(ScalarNode, node.value, (False, True)) - implicit = (node.tag == detected_tag), (node.tag == default_tag) - self.emit(ScalarEvent(alias, node.tag, implicit, node.value, - style=node.style)) - elif isinstance(node, SequenceNode): - implicit = (node.tag - == self.resolve(SequenceNode, node.value, True)) - self.emit(SequenceStartEvent(alias, node.tag, implicit, - flow_style=node.flow_style)) - index = 0 - for item in node.value: - self.serialize_node(item, node, index) - index += 1 - self.emit(SequenceEndEvent()) - elif isinstance(node, MappingNode): - implicit = (node.tag - == self.resolve(MappingNode, node.value, True)) - self.emit(MappingStartEvent(alias, node.tag, implicit, - flow_style=node.flow_style)) - for key, value in node.value: - self.serialize_node(key, node, None) - self.serialize_node(value, node, key) - self.emit(MappingEndEvent()) - self.ascend_resolver() - diff --git a/plugins_available/util/yaml/tokens.py b/plugins_available/util/yaml/tokens.py deleted file mode 100644 index 4d0b48a..0000000 --- a/plugins_available/util/yaml/tokens.py +++ /dev/null @@ -1,104 +0,0 @@ - -class Token(object): - def __init__(self, start_mark, end_mark): - self.start_mark = start_mark - self.end_mark = end_mark - def __repr__(self): - attributes = [key for key in self.__dict__ - if not key.endswith('_mark')] - attributes.sort() - arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) - for key in attributes]) - return '%s(%s)' % (self.__class__.__name__, arguments) - -#class BOMToken(Token): -# id = '' - -class DirectiveToken(Token): - id = '' - def __init__(self, name, value, start_mark, end_mark): - self.name = name - self.value = value - self.start_mark = start_mark - self.end_mark = end_mark - -class DocumentStartToken(Token): - id = '' - -class DocumentEndToken(Token): - id = '' - -class StreamStartToken(Token): - id = '' - def __init__(self, start_mark=None, end_mark=None, - encoding=None): - self.start_mark = start_mark - self.end_mark = end_mark - self.encoding = encoding - -class StreamEndToken(Token): - id = '' - -class BlockSequenceStartToken(Token): - id = '' - -class BlockMappingStartToken(Token): - id = '' - -class BlockEndToken(Token): - id = '' - -class FlowSequenceStartToken(Token): - id = '[' - -class FlowMappingStartToken(Token): - id = '{' - -class FlowSequenceEndToken(Token): - id = ']' - -class FlowMappingEndToken(Token): - id = '}' - -class KeyToken(Token): - id = '?' - -class ValueToken(Token): - id = ':' - -class BlockEntryToken(Token): - id = '-' - -class FlowEntryToken(Token): - id = ',' - -class AliasToken(Token): - id = '' - def __init__(self, value, start_mark, end_mark): - self.value = value - self.start_mark = start_mark - self.end_mark = end_mark - -class AnchorToken(Token): - id = '' - def __init__(self, value, start_mark, end_mark): - self.value = value - self.start_mark = start_mark - self.end_mark = end_mark - -class TagToken(Token): - id = '' - def __init__(self, value, start_mark, end_mark): - self.value = value - self.start_mark = start_mark - self.end_mark = end_mark - -class ScalarToken(Token): - id = '' - def __init__(self, value, plain, start_mark, end_mark, style=None): - self.value = value - self.plain = plain - self.start_mark = start_mark - self.end_mark = end_mark - self.style = style - diff --git a/plugins_available/weather.py b/plugins_available/weather.py deleted file mode 100644 index 9556b9f..0000000 --- a/plugins_available/weather.py +++ /dev/null @@ -1,72 +0,0 @@ -"weather, thanks to google" - -import os -import codecs -import thread -import urllib -from lxml import etree - -from util import hook - - -lock = thread.allocate_lock() -stalk = {} - - -def load_stalk(filename, mtimes={}): - if not os.path.exists(filename): - return {} - mtime = os.stat(filename).st_mtime - if mtimes.get(filename, 0) != mtime: - mtimes[filename] = mtime - return dict(x.strip().split(None, 1) for x in - codecs.open(filename, 'r', 'utf-8')) - - -def save_stalk(filename, houses): - out = codecs.open(filename, 'w', 'utf-8') - out.write('\n'.join('%s %s' % x for x in sorted(houses.iteritems()))) #heh - out.flush() - out.close() - - -@hook.command -def weather(bot, input): - ".weather [dontsave] -- queries the google weather API for weather data" - global stalk - - filename = os.path.join(bot.persist_dir, 'weather') - if not stalk: - with lock: - stalk = load_stalk(filename) - - nick = input.nick.lower() - loc = input.inp.strip() - dontsave = loc.endswith(" dontsave") - if dontsave: - loc = loc[:-9].strip().lower() - if not loc: # blank line - loc = stalk.get(nick, '') - if not loc: - return weather.__doc__ - - data = urllib.urlencode({'weather': loc.encode('utf-8')}) - url = 'http://www.google.com/ig/api?' + data - w = etree.parse(url).find('weather') - - if w.find('problem_cause') is not None: - return "Couldn't fetch weather data for '%s', try using a zip or " \ - "postal code." % input.inp - - info = dict((e.tag, e.get('data')) for e in w.find('current_conditions')) - info['city'] = w.find('forecast_information/city').get('data') - info['high'] = w.find('forecast_conditions/high').get('data') - info['low'] = w.find('forecast_conditions/low').get('data') - - input.reply('%(city)s: %(condition)s, %(temp_f)sF/%(temp_c)sC (H:%(high)sF'\ - ', L:%(low)sF), %(humidity)s, %(wind_condition)s.' % info) - - if not dontsave and loc != stalk.get(nick, ''): - with lock: - stalk[nick] = loc - save_stalk(filename, stalk) diff --git a/plugins_available/wikipedia.py b/plugins_available/wikipedia.py deleted file mode 100644 index 8c560ec..0000000 --- a/plugins_available/wikipedia.py +++ /dev/null @@ -1,57 +0,0 @@ -'''Searches wikipedia and returns first sentence of article -Scaevolus 2009''' - -import urllib -from lxml import etree -import re - -from util import hook - - -api_prefix = "http://en.wikipedia.org/w/api.php" -search_url = api_prefix + "?action=opensearch&search=%s&format=xml" - -paren_re = re.compile('\s*\(.*\)$') - - -@hook.command(hook='w(\s+.*|$)') -@hook.command -def wiki(query): - '''.w/.wiki -- gets first sentence of wikipedia ''' \ - '''article on ''' - - if not query.strip(): - return wiki.__doc__ - - q = search_url % (urllib.quote(query.strip(), safe='')) - x = etree.parse(q) - - ns = '{http://opensearch.org/searchsuggest2}' - items = x.findall(ns + 'Section/' + ns + 'Item') - - if items == []: - if x.find('error') is not None: - return 'error: %(code)s: %(info)s' % x.find('error').attrib - else: - return 'no results found' - - def extract(item): - return [item.find(ns + x).text for x in - ('Text', 'Description', 'Url')] - - title, desc, url = extract(items[0]) - - if 'may refer to' in desc: - title, desc, url = extract(items[1]) - - title = paren_re.sub('', title) - - if title.lower() not in desc.lower(): - desc = title + desc - - desc = re.sub('\s+', ' ', desc).strip() #remove excess spaces - - if len(desc) > 300: - desc = desc[:300] + '...' - - return '%s -- %s' % (desc, url) diff --git a/plugins_available/youtube.py b/plugins_available/youtube.py deleted file mode 100644 index 28ad6d8..0000000 --- a/plugins_available/youtube.py +++ /dev/null @@ -1,41 +0,0 @@ -import re -from lxml import etree -import locale - -from util import hook - - -def ytdata(id): - url = 'http://gdata.youtube.com/feeds/api/videos/' + id - x = etree.parse(url) - - # I can't figure out how to deal with schemas/namespaces properly :( - yt = '{http://gdata.youtube.com/schemas/2007}' - media = '{http://search.yahoo.com/mrss/}' - - rating = x.find('{http://schemas.google.com/g/2005}rating') - data = dict(rating.items()) - data['title'] = x.find('{http://www.w3.org/2005/Atom}title').text - data['views'] = locale.format('%d', int(x.find(yt + 'statistics').get( - 'viewCount')), 1) - length = int(x.find(media + 'group/' + yt + 'duration').get('seconds')) - data['length'] = '' - if length / 3600: # > 1 hour - data['length'] += str(length/3600) + 'h ' - if length / 60: # > 1 minute - data['length'] += str(length/60 % 60) + 'm ' - data['length'] += "%ds" % (length % 60) - - return data - -youtube_re = re.compile(r'.*youtube.*v=([-_a-z0-9]+)', flags=re.IGNORECASE) - - -#@hook.command(hook=r'(.*)', prefix=False) -def youtube(inp): - m = youtube_re.match(inp) - if m: - data = ytdata(m.group(1)) - return '\x02%(title)s\x02 - rated \x02%(average)s/%(max)s\x02 ' \ - '(%(numRaters)s) - views \x02%(views)s\x02 - length \x02' \ - '%(length)s\x02' % data