aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorsienkiew <sienkiew@d34015c8-bcbb-4646-8ac8-8ba5febf221d>2011-07-21 11:17:58 -0400
committersienkiew <sienkiew@d34015c8-bcbb-4646-8ac8-8ba5febf221d>2011-07-21 11:17:58 -0400
commitbe5a70d3aa1c30d7c86d77649b747de2838566ce (patch)
tree7c27103a4d37b61f5dba748672f0685536e667d0 /examples
parent77ce1e78848ba9eead2566e3bc55523aab4547e8 (diff)
downloadexyapps-be5a70d3aa1c30d7c86d77649b747de2838566ce.tar.gz
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
Diffstat (limited to 'examples')
-rw-r--r--examples/calc.g64
-rw-r--r--examples/expr.g21
-rw-r--r--examples/lisp.g13
-rw-r--r--examples/notes44
-rw-r--r--examples/xml.g66
5 files changed, 208 insertions, 0 deletions
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<<V>>: factor<<V>> {{ n = factor }}
+ ( "[+]" factor<<V>> {{ n = n+factor }}
+ | "-" factor<<V>> {{ n = n-factor }}
+ )* {{ return n }}
+
+ # A factor is the product and division of terms
+ rule factor<<V>>: term<<V>> {{ v = term }}
+ ( "[*]" term<<V>> {{ v = v*term }}
+ | "/" term<<V>> {{ v = v/term }}
+ )* {{ return v }}
+
+ # A term is a number, variable, or an expression surrounded by parentheses
+ rule term<<V>>:
+ NUM {{ return int(NUM) }}
+ | VAR {{ return lookup(V, VAR) }}
+ | "\\(" expr "\\)" {{ return expr }}
+ | "let" VAR "=" expr<<V>> {{ V = [(VAR, expr)] + V }}
+ "in" expr<<V>> {{ return expr }}
+%%
+if __name__=='__main__':
+ print 'Welcome to the calculator sample for Yapps 2.'
+ print ' Enter either "<expression>" or "set <var> <expression>",'
+ 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 <smurf@debian.org>
+
+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'<!\[CDATA\[.*?\]\]>' {{ return ['![CDATA['] }}
+ | r'<!' SP* id '[^>]*>' {{ return ['!doctype'] }}
+ | '<' SP* id SP* attributes SP* {{ startid = id }}
+ ( '>' nodes '</' SP* id SP* '>' {{ assert startid == id, 'Mismatched tags <%s> ... </%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 = ['<!-- hello -->',
+ 'some text',
+ '< bad xml',
+ '<br />',
+ '< spacey a = "foo" / >',
+ '<a href="foo">text ... </a>',
+ '<begin> middle </end>',
+ '<begin> <nested attr=\'baz\' another="hey"> foo </nested> <nested> bar </nested> </begin>',
+ ]
+ 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