SCG - Smacc examples

Stephane Ducasse ducasse at iam.unibe.ch
Sat Feb 15 21:40:38 UTC 2003


Hi

I thought some other people could like to have examples of SmaCC parser  
and Scanner.
Please note that I extracted that from the generated classes and that  
the method bodies
are then commented.

These parsers definitions has been made by roel and lukas.

Stef

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
BibEntry Parser and Scanner extracted from the generated class. Note  
that the method bodies are comments (as shown by the "")

parserDefinitionComment

	"%id <bracedBodyString> <bracketedBodyString>;

bibfile	: entry+  {Bib.BibFile new entries: '1'};

entry	: ""@"" <name> (<bracedBodyString> | <bracketedBodyString>)
		{Bib.BibEntry new key: '2' value asSymbol; body: (Bib.BodyParser  
parse: ('3' value copyFrom: 2 to: '3' value size - 1))} ;"


scannerDefinitionComment

	"<whitespace>			:	[\s]* ;
<name>				:	[a-z0-9\!\$\&\*\+\-\.\/\:\;\<\>\?\[\]\^\_\`\|]+	;

<bracedBodyString>		:	\{ ;		#rest is handled in the scanner itself!
<bracketedBodyString>	:	\( ;		#rest is handled in the scanner itself!"


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
TextStringToHTMLConverter


parserDefinitionComment

	"TEXSTRING		:	TEXPIECE*		{ | str |	str := WriteStream on: String new.
											nodes first do: [:string | str nextPutAll: string].
											str contents };

TEXPIECE		:	<acute> <char> <closingBracket>				{ self convert: '2'  
value as: #acute }
				|	<grave> <char> <closingBracket>				{ self convert: '2' value as:  
#grave}
				|	<circumflex> <char> <closingBracket>			{ self convert: '2' value  
as: #circumflex}
				|	<umlaut> <char> <closingBracket>				{ self convert: '2' value as:  
#umlaut}
				|	<tilde> <char> <closingBracket>				{ self convert: '2' value as:  
#tilde}
				|	<bar> <char> <closingBracket>				{ self convert: '2' value as:  
#bar}
				|	<dot> <char> <closingBracket>				{ self convert: '2' value as:  
#dot}
				|	<invCircumflex> <char> <closingBracket>		{ self convert: '2'  
value as: #invCircumflex}
				|	<arc> <char> <closingBracket>				{ self convert: '2' value as:  
#arc}
				|	<doubleQuote> <char> <closingBracket>		{ self convert: '2' value  
as: #doubleQuote}
				|	<altAcute> <char> <closingBracket>			{ self convert: '2' value  
as: #acute }
				|	<altGrave> <char> <closingBracket>			{ self convert: '2' value  
as: #grave}
				|	<altCircumflex> <char> <closingBracket>		{ self convert: '2'  
value as: #circumflex}
				|	<altUmlaut> <char> <closingBracket>			{ self convert: '2' value  
as: #umlaut}
				|	<altTilde> <char> <closingBracket>			{ self convert: '2' value  
as: #tilde}
				|	<altBar> <char> <closingBracket>				{ self convert: '2' value as:  
#bar}
				|	<altDot> <char> <closingBracket>				{ self convert: '2' value as:  
#dot}
				|	<altInvCircumflex> <char> <closingBracket>		{ self convert: '2'  
value as: #invCircumflex}
				|	<altArc> <char> <closingBracket>				{ self convert: '2' value as:  
#arc}
				|	<altDoubleQuote> <char> <closingBracket>		{ self convert: '2'  
value as: #doubleQuote}
				|	<alt2Acute> <char>							{ self convert: '2' value as: #acute }
				|	<alt2Grave> <char>							{ self convert: '2' value as: #grave}
				|	<alt2Circumflex> <char>						{ self convert: '2' value as:  
#circumflex}
				|	<alt2Umlaut> <char>							{ self convert: '2' value as: #umlaut}
				|	<alt2Tilde> <char>							{ self convert: '2' value as: #tilde}
				|	<alt2Bar> <char>								{ self convert: '2' value as: #bar}
				|	<alt2Dot> <char>								{ self convert: '2' value as: #dot}
				|	<cdif>										{ self lookup: #cdif}
				|	<inversedQuestionMark>						{ self lookup: #inversedQuestionMark}
				|	<oe>										{ self lookup: #oe}
				|	<ae>										{ self lookup: #ae}
				|	<ss>										{ self lookup: #ss}
				|	<smallRingedA>								{ self lookup: #smallRingedA}
				|	<capitalRingedA>							{ self lookup: #capitalRingedA}
				|	<smallSlashedO>							{ self lookup: #smallSlashedO}
				|	<capitalSlashedO>							{ self lookup: #capitalSlashedO}
				|	<nonBreakingSpace>							{ self lookup: #nonBreakingSpace}
				|	<doubleSlash>								{ self lookup: #doubleSlash}
				|	<noBackSlash>								{'1' value}
				|	<char>										{'1' value}
				|	<closingBracket>								{'1' value}
				|	<otherSlashedChar>							{'1' value}
		;"


scannerDefinitionComment

	"<char>						:	[a-zA-Z]				;
<closingBracket>				:	\}					;
<noBackSlash>				:	[^a-zA-Z\\\~\}]			;
<doubleSlash>				:	\\ \\					;
<otherSlashedChar>			:	\\ [^'\`\^\""\~\=\.\v\u\H]	;

#international characters
<acute>						:	\\ \' \{ 				;	# \'{ }
<grave>						:	\\ \` \{ 				;	# \`{ }
<circumflex>					:	\\ \^ \{	 			;	# \^{ }
<umlaut>					:	\\ \"" \{		 		;	# \""{ }
<tilde>						:	\\ \~ \{			 	;	# \~{ }
<bar>						:	\\ \= \{		 		;	# \={ }
<dot>						:	\\ \. \{			 	;	# \.{ }
<invCircumflex>				:	\\ v \{ 				;	# \v{ }
<arc>						:	\\ u \{		 		;	# \u{ }
<doubleQuote>				:	\\ H \{ 				;	# \H{ }

#Alternative form for international characters
<altAcute>					:	\{ \\ \'				;	# {\' }
<altGrave>					:	\{ \\ \`				;	# {\` }
<altCircumflex>				:	\{ \\ \^				;	# {\^ }
<altUmlaut>					:	\{ \\ \""				;	# {\"" }
<altTilde>					:	\{ \\ \~				;	# {\~ }
<altBar>						:	\{ \\ \=				;	# {\= }
<altDot>						:	\{ \\ \.				;	# {\. }
<altInvCircumflex>			:	\{ \\ v				;	# {\v }
<altArc>						:	\{ \\ \u				;	# {\u }
<altDoubleQuote>			:	\{ \\ \H				;	# {\H }

#Another alternative form for international characters
<alt2Acute>					:	\\ \'			;	# \'
<alt2Grave>					:	\\ \`			;	# \`
<alt2Circumflex>				:	\\ \^			;	# \^
<alt2Umlaut>				:	\\ \""			;	# \""
<alt2Tilde>					:	\\ \~			;	# \~
<alt2Bar>					:	\\ \=			;	# \=
<alt2Dot>					:	\\ \.			;	# \.

#special characters
<cdif>						:	\\ c \{ c \}			;	# \c{ }
<inversedQuestionMark>		:	\? \'				;	# ?`
<oe>						:	\\ o e			;	# \oe
<ae>						:	\\ a e			;	# \ae
<ss>						:	\\ s s			;	# {\ss}
<smallRingedA>				:	\\ a a			;	# \aa
<capitalRingedA>			:	\\ A A			;	# \AA
<smallSlashedO>			:	\\ o				;	# \o
<capitalSlashedO>			:	\\ O				;	# \O
<nonBreakingSpace>			:	\~				;	# ~
"


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%%%%%%%%%
SmallWiki parser

parserDefinitionComment

	"# options
%start				document ;

%left				 paragraphchar tablechar linkchar codechar unparsedchar ;
%left				<link> <alias> <codestart> <codeend> ;
%left				<horizontalrule> <header> <orderedlist> <unorderedlist>  
<table> <preformatted> ;
%left				<any> <newline> ;

# start token
document			: documentitem* 'documentitems' { Document new addAll:  
documentitems; yourself } ;
documentitem		: horizontalrule 'horizontalrule' { horizontalrule }
					| header 'header' { header }
					| orderedlist 'orderedlist' { orderedlist }
					| unorderedlist 'unorderedlist' { unorderedlist }
					| table 'table' { table }
					| preformatted 'preformatted' { preformatted }
					| paragraph 'paragraph' { paragraph } ;

# single-line
horizontalrule		: <horizontalrule> <newline> { HorizontalRule new } ;
header				: headerlevel 'level' unparsedstring 'string' <newline> {  
Header new text: string; level: level; yourself } ;
headerlevel			: <header>+ 'level' { level size } ;
paragraph			: paragraphtext 'text' <newline> { Paragraph new addAll:  
text; yourself } ;

# multi-line
orderedlist			: orderedlistitem+ 'listitems' { OrderedList new addAll:  
listitems; yourself } ;
orderedlistitem		: <orderedlist> paragraphtext 'text' <newline> {  
ListItem new addAll: text; yourself };

unorderedlist		: unorderedlistitem+ 'listitems' { UnorderedList new  
addAll: listitems; yourself } ;
unorderedlistitem	: <unorderedlist> paragraphtext 'text' <newline> {  
ListItem new addAll: text; yourself } ;

table				: tablerow+ 'rows' { Table new addAll: rows; yourself } ;
tablerow			: tablecell+ 'cells' <newline> { TableRow new addAll: cells;  
yourself } ;
tablecell			: <table> tabletext 'text' { TableCell new addAll: text;  
yourself } ;

preformatted		: preformattedline+ 'lines' { Preformatted new addAll:  
lines; yourself } ;
preformattedline		: <preformatted> unparsedstring 'string' <newline> {  
Text new text: string } ;

# internal-, external- and mail-references
link					: <link> linkreference 'linkreference' <link> { linkreference  
} ;
linkreference		: linkstring 'text' <alias> linkstring 'reference' {  
(Link newTo: reference from: structure) text: text; yourself }
					| linkstring 'reference'  { Link newTo: reference from: structure  
} ;

# code blocks
code				: <codestart> codeitem 'code' <codeend> { Code new code: code;  
yourself } ;
codeitem			: codeblock+ 'code' { | stream |
						stream := WriteStream on: String new.
						code do: [ :each | stream nextPutAll: each ].
						^stream contents } ;
codeblock			: codestring 'code' { code }
					| <codestart> codeitem 'code' <codeend> { | stream |
						stream := WriteStream on: String new.
						stream nextPut: $[; nextPutAll: code; nextPut: $].
						^stream contents } ;

# paragraph- and table-text
paragraphtext		: paragraphtextitem* 'paragraphtextitem' {  
paragraphtextitem } ;
paragraphtextitem	: paragraphstring 'paragraphstring' { Text new text:  
paragraphstring; yourself }
					| code 'code' { code }
					| link 'link' { link } ;
tabletext			: tabletextitem* 'tabletextitem' { tabletextitem } ;
tabletextitem		: tablestring 'tablestring' { Text new text:  
tablestring; yourself }
					| code 'code' { code }
					| link 'link' { link } ;

# unparsed-, paragraph-, table- and link-string
paragraphstring		: paragraphchar+ 'paragraphchar' { String withAll:  
paragraphchar } ;
paragraphchar		: <any> { '1' value first } | <horizontalrule> { '1'  
value first } | <header> { '1' value first } | <orderedlist> { '1'  
value first }
					| <unorderedlist> { '1' value first } | <table> { '1' value first  
} | <preformatted> { '1' value first } | <alias> { '1' value first }
					| <codeend> { '1' value first } ;
tablestring			: tablechar+ 'tablechar' { String withAll: tablechar } ;
tablechar			: <any> { '1' value first } | <horizontalrule> { '1' value  
first } | <header> { '1' value first } | <orderedlist> { '1' value  
first }
					| <unorderedlist> { '1' value first } | <preformatted> { '1' value  
first } | <alias> { '1' value first } | <codeend> { '1' value first } ;
linkstring			: linkchar+ 'linkchar' { String withAll: linkchar } ;
linkchar				: <any> { '1' value first } | <horizontalrule> { '1' value  
first } | <header> { '1' value first } | <orderedlist> { '1' value  
first }
					| <unorderedlist> { '1' value first } | <table> { '1' value first  
} | <preformatted> { '1' value first } | <codestart> { '1' value first }
					| <codeend> { '1' value first } ;
codestring			: codechar+ 'codechar' { String withAll: codechar } ;
codechar			: <any> { '1' value first } | <horizontalrule> { '1' value  
first } | <header> { '1' value first } | <orderedlist> { '1' value  
first }
					| <unorderedlist> { '1' value first } | <table> { '1' value first  
} | <preformatted> { '1' value first } | <link> { '1' value first }
					| <alias> { '1' value first } | <newline> { '1' value first } ;
unparsedstring		: unparsedchar+ 'unparsedchar' { String withAll:  
unparsedchar } ;
unparsedchar		: <any> { '1' value first } | <horizontalrule> { '1'  
value first } | <header> { '1' value first } | <orderedlist> { '1'  
value first }
					| <unorderedlist> { '1' value first } | <table> { '1' value first  
} | <preformatted> { '1' value first } | <link> { '1' value first }
					| <alias> { '1' value first } | <codestart> { '1' value first } |  
<codeend> { '1' value first } ;"

scannerDefinitionComment

	"# newline
<newline>:			\r\n | \r | \n ;

# line
<horizontalrule>:	\_ ;
<header>: 			\! ;
<orderedlist>:		\# ;
<unorderedlist>:		\- ;
<table>:			\| ;
<preformatted>:		\= ;

# text
<link>:				\* ;
<alias>:				\> ;
<codestart>:		\[ ;
<codeend>:			\] ;

# other
<any>:				. ;"




Prof. Dr. Stéphane DUCASSE (ducasse at iam.unibe.ch)  
http://www.iam.unibe.ch/~ducasse/
  "if you knew today was your last day on earth, what would you do
  different? ... especially if, by doing something different, today
  might not be your last day on earth" Calvin&Hobbes



More information about the Squeak-dev mailing list