From be5a70d3aa1c30d7c86d77649b747de2838566ce Mon Sep 17 00:00:00 2001 From: sienkiew Date: Thu, 21 Jul 2011 15:17:58 +0000 Subject: initial import of yapps from debian sources git-svn-id: http://svn.stsci.edu/svn/ssb/etal/exyapps/trunk@356 d34015c8-bcbb-4646-8ac8-8ba5febf221d --- examples/calc.g | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ examples/expr.g | 21 ++++++++++++++++++ examples/lisp.g | 13 ++++++++++++ examples/notes | 44 ++++++++++++++++++++++++++++++++++++++ examples/xml.g | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 208 insertions(+) create mode 100644 examples/calc.g create mode 100644 examples/expr.g create mode 100644 examples/lisp.g create mode 100644 examples/notes create mode 100644 examples/xml.g (limited to 'examples') diff --git a/examples/calc.g b/examples/calc.g new file mode 100644 index 0000000..5432855 --- /dev/null +++ b/examples/calc.g @@ -0,0 +1,64 @@ +globalvars = {} # We will store the calculator's variables here + +def lookup(map, name): + for x,v in map: + if x == name: return v + if not globalvars.has_key(name): print 'Undefined (defaulting to 0):', name + return globalvars.get(name, 0) + +def stack_input(scanner,ign): + """Grab more input""" + scanner.stack_input(raw_input(">?> ")) + +%% +parser Calculator: + ignore: "[ \r\t\n]+" + ignore: "[?]" {{ stack_input }} + + token END: "$" + token NUM: "[0-9]+" + token VAR: "[a-zA-Z_]+" + + # Each line can either be an expression or an assignment statement + rule goal: expr<<[]>> END {{ print '=', expr }} + {{ return expr }} + | "set" VAR expr<<[]>> END {{ globalvars[VAR] = expr }} + {{ print VAR, '=', expr }} + {{ return expr }} + + # An expression is the sum and difference of factors + rule expr<>: factor<> {{ n = factor }} + ( "[+]" factor<> {{ n = n+factor }} + | "-" factor<> {{ n = n-factor }} + )* {{ return n }} + + # A factor is the product and division of terms + rule factor<>: term<> {{ v = term }} + ( "[*]" term<> {{ v = v*term }} + | "/" term<> {{ v = v/term }} + )* {{ return v }} + + # A term is a number, variable, or an expression surrounded by parentheses + rule term<>: + NUM {{ return int(NUM) }} + | VAR {{ return lookup(V, VAR) }} + | "\\(" expr "\\)" {{ return expr }} + | "let" VAR "=" expr<> {{ V = [(VAR, expr)] + V }} + "in" expr<> {{ return expr }} +%% +if __name__=='__main__': + print 'Welcome to the calculator sample for Yapps 2.' + print ' Enter either "" or "set ",' + print ' or just press return to exit. An expression can have' + print ' local variables: let x = expr in expr' + # We could have put this loop into the parser, by making the + # `goal' rule use (expr | set var expr)*, but by putting the + # loop into Python code, we can make it interactive (i.e., enter + # one expression, get the result, enter another expression, etc.) + while 1: + try: s = raw_input('>>> ') + except EOFError: break + if not s.strip(): break + parse('goal', s) + print 'Bye.' + diff --git a/examples/expr.g b/examples/expr.g new file mode 100644 index 0000000..ae807b7 --- /dev/null +++ b/examples/expr.g @@ -0,0 +1,21 @@ +parser Calculator: + token END: "$" + token NUM: "[0-9]+" + + rule goal: expr END {{ return expr }} + + # An expression is the sum and difference of factors + rule expr: factor {{ v = factor }} + ( "[+]" factor {{ v = v+factor }} + | "-" factor {{ v = v-factor }} + )* {{ return v }} + + # A factor is the product and division of terms + rule factor: term {{ v = term }} + ( "[*]" term {{ v = v*term }} + | "/" term {{ v = v/term }} + )* {{ return v }} + + # A term is either a number or an expression surrounded by parentheses + rule term: NUM {{ return atoi(NUM) }} + | "\\(" expr "\\)" {{ return expr }} diff --git a/examples/lisp.g b/examples/lisp.g new file mode 100644 index 0000000..551e6f9 --- /dev/null +++ b/examples/lisp.g @@ -0,0 +1,13 @@ +parser Lisp: + ignore: r'\s+' + token NUM: r'[0-9]+' + token ID: r'[-+*/!@$%^&=.a-zA-Z0-9_]+' + token STR: r'"([^\\"]+|\\.)*"' + + rule expr: ID {{ return ('id',ID) }} + | STR {{ return ('str',eval(STR)) }} + | NUM {{ return ('num',int(NUM)) }} + | r"\(" + {{ e = [] }} # initialize the list + ( expr {{ e.append(expr) }} ) * # put each expr into the list + r"\)" {{ return e }} # return the list diff --git a/examples/notes b/examples/notes new file mode 100644 index 0000000..aa45bfb --- /dev/null +++ b/examples/notes @@ -0,0 +1,44 @@ +Hints +##### + +Some additional hints for your edification. + +Author: Matthias Urlichs + +How to process C preprocessor codes: +==================================== + +Rudimentary include handling has been added to the parser by me. + +However, if you want to do anything fancy, like for instance whatever +the C preprocessor does, things get more complicated. Fortunately, +there's already a nice tool to handle C preprocessing -- CPP itself. + +If you want to report errors correctly in that situation, do this: + + def set_line(s,m): + """Fixup the scanner's idea of the current line""" + s.filename = m.group(2) + line = int(m.group(1)) + s.del_line = line - s.line + + %% + parser whatever: + ignore: '^#\s*(\d+)\s*"([^"\n]+)"\s*\n' {{ set_line }} + ignore: '^#.*\n' + + [...] + %% + if __name__=='__main__': + import sys,os + for a in sys.argv[1:]: + f=os.popen("cpp "+repr(a),"r") + + P = whatever(whateverScanner("", filename=a, file=f)) + try: P.goal() + except runtime.SyntaxError, e: + runtime.print_error(e, P._scanner) + sys.exit(1) + + f.close() + diff --git a/examples/xml.g b/examples/xml.g new file mode 100644 index 0000000..cec2709 --- /dev/null +++ b/examples/xml.g @@ -0,0 +1,66 @@ +#!/usr/bin/python2 + +# xml.g +# +# Amit J. Patel, August 2003 +# +# Simple (non-conforming, non-validating) parsing of XML documents, +# based on Robert D. Cameron's "REX" shallow parser. It doesn't +# handle CDATA and lots of other stuff; it's meant to demonstrate +# Yapps, not replace a proper XML parser. + +%% + +parser xml: + token nodetext: r'[^<>]+' + token attrtext_singlequote: "[^']*" + token attrtext_doublequote: '[^"]*' + token SP: r'\s' + token id: r'[a-zA-Z_:][a-zA-Z0-9_:.-]*' + + rule node: + r'' {{ return ['!--comment'] }} + | r'' {{ return ['![CDATA['] }} + | r']*>' {{ return ['!doctype'] }} + | '<' SP* id SP* attributes SP* {{ startid = id }} + ( '>' nodes '' {{ assert startid == id, 'Mismatched tags <%s> ... ' % (startid, id) }} + {{ return [id, attributes] + nodes }} + | '/\s*>' {{ return [id, attributes] }} + ) + | nodetext {{ return nodetext }} + + rule nodes: {{ result = [] }} + ( node {{ result.append(node) }} + ) * {{ return result }} + + rule attribute: id SP* '=' SP* + ( '"' attrtext_doublequote '"' {{ return (id, attrtext_doublequote) }} + | "'" attrtext_singlequote "'" {{ return (id, attrtext_singlequote) }} + ) + + rule attributes: {{ result = {} }} + ( attribute SP* {{ result[attribute[0]] = attribute[1] }} + ) * {{ return result }} + +%% + +if __name__ == '__main__': + tests = ['', + 'some text', + '< bad xml', + '
', + '< spacey a = "foo" / >', + 'text ... ', + ' middle ', + ' foo bar ', + ] + print + print '____Running tests_______________________________________' + for test in tests: + print + try: + parser = xml(xmlScanner(test)) + output = '%s ==> %s' % (repr(test), repr(parser.node())) + except (yappsrt.SyntaxError, AssertionError), e: + output = '%s ==> FAILED ==> %s' % (repr(test), e) + print output -- cgit