Click here to Skip to main content
12,402,603 members (73,120 online)
Click here to Skip to main content

Stats

126.2K views
1.8K downloads
117 bookmarked
Posted

Parsing Expression Grammar Support for C# 3.0 Part 1 - PEG Lib and Parser Generator

, 7 Oct 2008 CPOL
Introduction to the parsing method PEG with library and parser generator
PEG_GrammarExplorer
Documents
PEG_GrammarExplorer_fromCP-Dateien
PEG_GrammerExplorer.jpg
mssccprj.scc
PEG Explorer
mssccprj.scc
PEG Explorer.csproj.user
Properties
vssver2.scc
vssver2.scc
PegBase
mssccprj.scc
Properties
vssver2.scc
vssver2.scc
PegSamples
BasicEncodingRules
input
CDURKR2URKR125195
DefiniteLengthForm
CDURKR2URKR125195
hello
TDAUTPTEUR0100011.tap3
vssver2.scc
hello
IndefiniteLengthForm
DefiniteLengthForm
TDAUTPTEUR0100011.tap3
TDAUTPTEUR0100011.tap3
TDAUTPTEUR0100011.tap3
TDAUTPTEUR0100011_withError.tap3
vssver2.scc
vssver2.scc
calc0_direct
input
vssver2.scc
vssver2.scc
calc0_tree
input
vssver2.scc
vssver2.scc
CSharp3
docu
input
vssver2.scc
vssver2.scc
C_KernighanRitchie2
input
vssver2.scc
vssver2.scc
EMail
input
vssver2.scc
vssver2.scc
Json
input
vssver2.scc
peg_template
vssver2.scc
vssver2.scc
mssccprj.scc
PEG Samples.csproj.user
PegGenerator
input
C#
TestCases
C#
.cs
vssver2.scc
vssver2.scc
vssver2.scc
vssver2.scc
Properties
vssver2.scc
python_2_5_2
input
adwords
awapi_python_samples_1.0.0
src
decoratorators_01
vssver2.scc
Problems
Sample PEG Console Parser
PEG Console Parser
input
Properties
Sample PEG Console Parser.csproj.user
vssver2.scc
PEG_GrammarExplorer_Submission
PEG_GrammerExplorer.jpg
PEG_GrammerExplorer.zip
#!/usr/local/bin/python

# tabview.py -- View a tab-delimited file in a spreadsheet-like display.
# Contributed by A.M. Kuchling <amk@amk.ca>
#
# The tab-delimited file is displayed on screen.  The highlighted
# position is shown in the top-left corner of the screen; below it are
# shown the contents of that cell.
#
#  Movement keys are:
#    Cursor keys: Move the highlighted cell, scrolling if required.
#    Q or q     : Quit
#    TAB        : Page right a screen
#    Home       : Move to the start of this line
#    End        : Move to the end of this line
#    PgUp/PgDn  : Move a page up or down
#    Insert     : Memorize this position
#    Delete     : Return to memorized position (if any)
#
# TODO : 
#    A 'G' for Goto: enter a cell like AA260 and move there
#    A key to re-read the tab-delimited file
#
# Possible projects:
#    Allow editing of cells, and then saving the modified data
#    Add formula evaluation, and you've got a simple spreadsheet
# program.  (Actually, you should allow displaying both via curses and
# via a Tk widget.)  
#

import curses, re, string

def yx2str(y,x):
    "Convert a coordinate pair like 1,26 to AA2"
    if x<26: s=chr(65+x)
    else:
	x=x-26
	s=chr(65+ (x/26) ) + chr(65+ (x%26) )
    s=s+str(y+1)
    return s

coord_pat = re.compile('^(?P<x>[a-zA-Z]{1,2})(?P<y>\d+)$')

def str2yx(s):
    "Convert a string like A1 to a coordinate pair like 0,0"
    match = coord_pat.match(s)
    if not match: return None
    y,x = match.group('y', 'x')
    x = string.upper(x)
    if len(x)==1: x=ord(x)-65
    else:
	x= (ord(x[0])-65)*26 + ord(x[1])-65 + 26
    return string.atoi(y)-1, x

assert yx2str(0,0) == 'A1'
assert yx2str(1,26) == 'AA2'
assert str2yx('AA2') == (1,26)
assert str2yx('B2') == (1,1)
	
class TabFile:
    def __init__(self, scr, filename, column_width=20):
	self.scr=scr ; self.filename = filename
	self.column_width = column_width
	f=open(filename, 'r')
	self.data = []
	while (1):
	    L=f.readline()
	    if L=="": break
	    self.data.append( string.split(L, '\t') )
#	    if len(self.data)>6: break # XXX
	self.x, self.y = 0,0
	self.win_x, self.win_y = 0,0
	self.max_y, self.max_x = self.scr.getmaxyx()
	self.num_columns = int(self.max_x/self.column_width)
	self.scr.clear()	
	self.display()

    def move_to_end(self):
	"""Move the highlighted location to the end of the current line."""

	# This is a method because I didn't want to have the code to 
	# handle the End key be aware of the internals of the TabFile object.
	yp=self.y+self.win_y ; xp=self.x+self.win_x
	if len(self.data)<=yp: end=0
	else: end=len(self.data[yp])-1
	
	# If the end column is on-screen, just change the
	# .x value appropriately.
	if self.win_x <= end < self.win_x + self.num_columns:
	    self.x = end - self.win_x
	else:
	    if end<self.num_columns:
		self.win_x = 0 ; self.x = end
	    else:
		self.x = self.num_columns-1
		self.win_x = end-self.x
	        
	
    def display(self):
	"""Refresh the current display"""
	
	self.scr.addstr(0,0, 
			yx2str(self.y + self.win_y, self.x+self.win_x)+'    ',
			curses.A_REVERSE)

	for y in range(0, self.max_y-3):
	    self.scr.move(y+2,0) ; self.scr.clrtoeol()
	    for x in range(0, int(self.max_x / self.column_width) ):
		self.scr.attrset(curses.A_NORMAL)
		yp=y+self.win_y ; xp=x+self.win_x
		if len(self.data)<=yp: s=""
		elif len(self.data[yp])<=xp: s=""
		else: s=self.data[yp][xp]
		s = string.ljust(s, 15)[0:15]
		if x==self.x and y==self.y: self.scr.attrset(curses.A_STANDOUT)
		self.scr.addstr(y+2, x*self.column_width, s)

	yp=self.y+self.win_y ; xp=self.x+self.win_x
	if len(self.data)<=yp: s=""
	elif len(self.data[yp])<=xp: s=""
	else: s=self.data[yp][xp]

	self.scr.move(1,0) ; self.scr.clrtoeol()
	self.scr.addstr(s[0:self.max_x])
	self.scr.refresh()

def main(stdscr):
    import string, curses, sys

    if len(sys.argv)==1:
	print 'Usage: tabview.py <filename>'
	return
    filename=sys.argv[1]

    # Clear the screen and display the menu of keys
    stdscr.clear()
    file = TabFile(stdscr, filename)
    
    # Main loop:
    while (1):
	stdscr.move(file.y+2, file.x*file.column_width)     # Move the cursor
	c=stdscr.getch()		# Get a keystroke
	if 0<c<256:
	    c=chr(c)
	    # Q or q exits
	    if c in 'Qq': break  
	    # Tab pages one screen to the right
	    elif c=='\t':
		file.win_x = file.win_x + file.num_columns
		file.display()
	    else: pass                  # Ignore incorrect keys

	# Cursor keys
	elif c==curses.key_up:
	    if file.y == 0:
		if file.win_y>0: file.win_y = file.win_y - 1
	    else: file.y=file.y-1
	    file.display()
	elif c==curses.key_down:
	    if file.y < file.max_y-3 -1: file.y=file.y+1
	    else: file.win_y = file.win_y+1
	    file.display()
	elif c==curses.key_left:
	    if file.x == 0:
		if file.win_x>0: file.win_x = file.win_x - 1
	    else: file.x=file.x-1
	    file.display()
	elif c==curses.key_right:
	    if file.x < int(file.max_x/file.column_width)-1: file.x=file.x+1
	    else: file.win_x = file.win_x+1
	    file.display()

	# Home key moves to the start of this line
	elif c==curses.key_home:
	    file.win_x = file.x = 0
	    file.display()
	# End key moves to the end of this line
	elif c==curses.key_end:
	    file.move_to_end()
	    file.display()

	# PageUp moves up a page
	elif c==curses.key_ppage:
	    file.win_y = file.win_y - (file.max_y - 2)
	    if file.win_y<0: file.win_y = 0
	    file.display()
	# PageDn moves down a page
	elif c==curses.key_npage:
	    file.win_y = file.win_y + (file.max_y - 2)
	    if file.win_y<0: file.win_y = 0
	    file.display()
	
	# Insert memorizes the current position
	elif c==curses.key_ic:
	    file.save_y, file.save_x = file.y + file.win_y, file.x + file.win_x
	# Delete restores a saved position
	elif c==curses.key_dc:
	    if hasattr(file, 'save_y'):
		file.x = file.y = 0
		file.win_y, file.win_x = file.save_y, file.save_x
		file.display()
        else: 
	    stdscr.addstr(0,50, curses.keyname(c)+ ' pressed')
	    stdscr.refresh()
	    pass			# Ignore incorrect keys

if __name__=='__main__':
    import curses, traceback
    try:
	# Initialize curses
	stdscr=curses.initscr()
	# Turn off echoing of keys, and enter cbreak mode,
	# where no buffering is performed on keyboard input
	curses.noecho() ; curses.cbreak()

	# In keypad mode, escape sequences for special keys
	# (like the cursor keys) will be interpreted and
	# a special value like curses.key_left will be returned
	stdscr.keypad(1)
	main(stdscr)			# Enter the main loop
	# Set everything back to normal
	stdscr.keypad(0)
	curses.echo() ; curses.nocbreak()
	curses.endwin()			# Terminate curses
    except:
        # In the event of an error, restore the terminal
	# to a sane state.
	stdscr.keypad(0)
	curses.echo() ; curses.nocbreak()
	curses.endwin()
	traceback.print_exc()		# Print the exception



By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Martin.Holzherr
Switzerland Switzerland
No Biography provided

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160721.1 | Last Updated 7 Oct 2008
Article Copyright 2008 by Martin.Holzherr
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid