Excellent!
It would be great if you could setup a github project for BAS2NIM using Python.
Building Recursive Descent Parsers with PythonPyparsing provides a basic framework for creating recursive-descent parsers, taking care of the overhead functions of scanning the input string, handling expression mismatches, selecting the longest of matching alternatives, invoking callback functions, and returning the parsed results. This leaves developers free to focus on their grammar design and the design and implementation of corresponding token processing. Pyparsing's nature as a combinator allows developers to scale their applications from simple tokenizers up to complex grammar processors. It is a great way to get started with your next parsing project!
#
# simpleArith.py
#
# Example of defining an arithmetic expression parser using
# the operatorPrecedence helper method in pyparsing.
#
# Copyright 2006, by Paul McGuire
#
from pyparsing import *
integer = Word(nums).setParseAction(lambda t:int(t[0]))
variable = Word(alphas,exact=1)
operand = integer | variable
expop = Literal('^')
signop = oneOf('+ -')
multop = oneOf('* /')
plusop = oneOf('+ -')
factop = Literal('!')
# To use the operatorPrecedence helper:
# 1. Define the "atom" operand term of the grammar.
# For this simple grammar, the smallest operand is either
# and integer or a variable. This will be the first argument
# to the operatorPrecedence method.
# 2. Define a list of tuples for each level of operator
# precendence. Each tuple is of the form
# (opExpr, numTerms, rightLeftAssoc, parseAction), where
# - opExpr is the pyparsing expression for the operator;
# may also be a string, which will be converted to a Literal
# - numTerms is the number of terms for this operator (must
# be 1 or 2)
# - rightLeftAssoc is the indicator whether the operator is
# right or left associative, using the pyparsing-defined
# constants opAssoc.RIGHT and opAssoc.LEFT.
# - parseAction is the parse action to be associated with
# expressions matching this operator expression (the
# parse action tuple member may be omitted)
# 3. Call operatorPrecedence passing the operand expression and
# the operator precedence list, and save the returned value
# as the generated pyparsing expression. You can then use
# this expression to parse input strings, or incorporate it
# into a larger, more complex grammar.
#
expr = operatorPrecedence( operand,
[("!", 1, opAssoc.LEFT),
("^", 2, opAssoc.RIGHT),
(signop, 1, opAssoc.RIGHT),
(multop, 2, opAssoc.LEFT),
(plusop, 2, opAssoc.LEFT),]
)
test = ["9 + 2 + 3",
"9 + 2 * 3",
"(9 + 2) * 3",
"(9 + -2) * 3",
"(9 + -2) * 3^2^2",
"(9! + -2) * 3^2^2",
"M*X + B",
"M*(X + B)",
"1+2*-3^4*5+-+-6",]
for t in test:
print(t)
print(expr.parseString(t))
print()
jrs@laptop:~/bas2nim/pyparsing-2.0.1/examples$ python simpleArith.py
9 + 2 + 3
[[9, '+', 2, '+', 3]]
()
9 + 2 * 3
[[9, '+', [2, '*', 3]]]
()
(9 + 2) * 3
[[[9, '+', 2], '*', 3]]
()
(9 + -2) * 3
[[[9, '+', ['-', 2]], '*', 3]]
()
(9 + -2) * 3^2^2
[[[9, '+', ['-', 2]], '*', [3, '^', [2, '^', 2]]]]
()
(9! + -2) * 3^2^2
[[[[9, '!'], '+', ['-', 2]], '*', [3, '^', [2, '^', 2]]]]
()
M*X + B
[[['M', '*', 'X'], '+', 'B']]
()
M*(X + B)
[['M', '*', ['X', '+', 'B']]]
()
1+2*-3^4*5+-+-6
[[1, '+', [2, '*', ['-', [3, '^', 4]], '*', 5], '+', ['-', ['+', ['-', 6]]]]]
()
jrs@laptop:~/bas2nim/pyparsing-2.0.1/examples$
#
# cLibHeader.py
#
# A simple parser to extract API doc info from a C header file
#
# Copyright, 2012 - Paul McGuire
#
from pyparsing import Word, alphas, alphanums, Combine, oneOf, Optional, delimitedList, Group, Keyword
testdata = """
int func1(float *vec, int len, double arg1);
int func2(float **arr, float *vec, int len, double arg1, double arg2);
"""
ident = Word(alphas, alphanums + "_")
vartype = Combine( oneOf("float double int char") + Optional(Word("*")), adjacent = False)
arglist = delimitedList(Group(vartype("type") + ident("name")))
functionCall = Keyword("int") + ident("name") + "(" + arglist("args") + ")" + ";"
for fn,s,e in functionCall.scanString(testdata):
print(fn.name)
for a in fn.args:
print(" - %(name)s (%(type)s)" % a)
jrs@laptop:~/bas2nim/pyparsing-2.0.1/examples$ python cLibHeader.py
func1
- vec (float*)
- len (int)
- arg1 (double)
func2
- arr (float**)
- vec (float*)
- len (int)
- arg1 (double)
- arg2 (double)
jrs@laptop:~/bas2nim/pyparsing-2.0.1/examples$