develooper Front page | perl.recdescent | Postings from June 2005

space-separated tokens (FAQ?)

Thread Next
From:
Scott
Date:
June 26, 2005 11:31
Subject:
space-separated tokens (FAQ?)
Message ID:
20050626182805.GG12004@DrMemory.localdomain
Please forgive me if this an FAQ. I am new to the world of RecDescent
and grammars in general. I'm assisting on a project for which the
original grammar was developed by someone else; making my own
additions, learning (sometimes) as I go. Not a pro, just dabbling.

I've tried to distill the grammar down for this post, but again, I
apologize if it is too long to digest. If you don't like it, you can
say, in our full grammar: ex R3 up.

I can't for the life of me figure out how to ensure that the tokens
are separated by whitespace, so that, eg 
   5 pu 2n mu 3 
would not be confused with
   5 pu 2nm 

I tried setting $Parse::RecDescent::skip = '[ \t]+' and every line was
bad. Is this separation something that needs to be dealt with in the
rules, and if so how?

TIA,
Scott Swanson

<code>
package SFNParse;

use Parse::RecDescent;

# Note: the grammar is stripped down, so a lot of these don't appear in it.
our %abbrevs = (
	# Hands (X-axis)
	'L'=>'left','R'=>'right','M'=>'middle',	
	# z-axis
	'n'=>'near','f'=>'far', 'a'=>'axial',
	# x-axis
	'o'=>'outer', 'i'=>'inner', 'm'=>'middle',
	# y-axis
	't'=>'top', 'c'=>'center','b'=>'bottom',	
	# Directions
	'dx'=>'distally','px'=>'proximally','lr'=>'from left to right','rl'=>'from right to left','nf'=>'near to far', 'fn'=>'far to near',
	'up'=>'upwards', 'dn'=>'downwards',
	'da'=>'down and away from you','ua'=>'up and away from you','dt'=>'down and towards you','ut'=>'up and towards you',
	'tw'=>'towards you','aw'=>'away from you','io'=>'from centre out','oi'=>'from outside to centre',
	'lor'=>'left over right', 'rol'=>'right over left', 
	# Twists
	'>'=>"a half turn away from you",'>>'=>"a full turn away from you",'<'=>"a half turn towards you",'<<'=>"a full turn towards you",
	# 'Descriptor' strings (added VS, changed text of CS, anticipating 'mid')
	'DS'=>'diagonal','SS'=>'straight','XS'=>'crossed','CS'=>'centre','TV'=>'transverse',
		'VS'=>'vertical','DM'=>'diamond',
	# Bodyparts (. means 'in the figure')
	'1'=>'thumb', '2'=>'forefinger', '3'=>'middle finger','4'=>'ring finger','5'=>'little finger',
	'P'=>'palm','H'=>'hand','W'=>'wrist','O'=>'mouth','.'=>' ','B'=>'back of hand',
		'T'=>'toe or etc', 'F'=>'fingers', 
	# Commands (added hu,hd)
	'pu'=>'pick up','gr'=>'grasp','hu'=>'hook up','hd'=>'hook down',
	'kl'=>'keep loose','ls'=>'let slip','ht'=>'hold tight','ex'=>'extend',','=>'then..',
	'na'=>'navaho','tr'=>'transfer','fl'=>'flip','<=>'=>'exchange',
	'mo'=>'over','mu'=>'under','mt'=>'through',
	'mb'=>'between',
	'rep'=>'repeat', 'rot'=>'rotate','rel'=>'release','ret'=>'return','pnt'=>'point',
	);

my $grammar = q {
move: (rel_move | take ) stringdesc	{"$item[1] $item[2]";}
take: ("pu" | "gr" | "hu" | "hd") direction(?) {$SFNParse::abbrevs{$item[1]}." ".$item[2][0];}
rel_move: ("mo" | "mu" | "mt") direction(?) {"move" . "$item[2][0] ".$SFNParse::abbrevs{$item[1]};}
stringdesc: strings {$item[1];}
strings: string(s) {join(" / ", @{$item[1]});}
string:		( mnoose | mstring )		
mnoose:	 manipulator "N" height(?){"$item[3][0] $item[1]  noose";}
mstring: manipulator height(?) side(?) lat(?) descriptor(?){join(" ", @{$item[2]},@{$item[3]},@{$item[4]},$item[1],@{$item[5]}," string");}
side:	("n" | "f" | "a") {$SFNParse::abbrevs{$item[1]};}
lat:	("i" | "o" | "m") {$SFNParse::abbrevs{$item[1]};}
height:	("t" | "c" | "b") {$SFNParse::abbrevs{$item[1]};}
descriptor: ("DS" | "XS" | "CS" | "SS" | "TV" | "VS" | "DM") {$SFNParse::abbrevs{$item[1]};}
direction:("px" | "dx" | "lr" | "rl" | "nf" | "fn") {$SFNParse::abbrevs{$item[1]};}
manipulator: hand(?) bodypart(s) {"$item[1][0] ".join("/", @{$item[2]});}
hand: ("L" | "R" | "M")	{$SFNParse::abbrevs{$item[1]};}
bodypart:("1" | "2" | "3" | "4" | "5" | "P" | "H") {$SFNParse::abbrevs{$item[1]};}
action: manipulator move(s) {$item[1] . " " . join (", ", @{$item[2]});}
fullmove:  action modifier(?) {$item[1].(($item[2][0]) ? " and ". $item[2][0] : "");}
modifier: ("ex" | "ret" | "si" | "kl" | ",")	{$SFNParse::abbrevs{$item[1]};}
validstep: code_ref | repeat | fullmove | voice
stepline: /\\\{?/ validstep /\\\}?/ comment(?)	{"$item[1] $item[2] $item[3] $item[4][0]";}
comment: "#" /.+/ {"($item[2])";}
code_ref: "[" /\w+/ "]"	{ "perform $item[2]";}
voice:	"v" /.+/ {'"'.$item[2].'"';}
repeat:	"rep" stepnumber "-" stepnumber {"repeat steps $item[2] to $item[4] "}
stepnumber: /\d+/

};

my $parser = new Parse::RecDescent ($grammar) or die "Bad grammar!\n";

while (<DATA>) {
  my $text = $parser->stepline($_) || "Error: $_";
  print "$text\n";
}
__DATA__
1 pu 5f
1 pu 5tfo
1 mu 2n pu 5cni
1 pu 2n mu 5cni # this is wrong
1mu2npu5cni     # Yucch! But it parses....

</code>



Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About