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
|