`[<<][libprim][>>][..]`
Tue Aug 18 08:58:30 CEST 2009

## PEG/LEG

```Trying out this[1].

The best way to understand is the metacircular example: The grammar
for peg grammars is shown below.

Grammar         <- Spacing Definition+ EndOfFile

Definition      <- Identifier LEFTARROW Expression
Expression      <- Sequence ( SLASH Sequence )*
Sequence        <- Prefix*
Prefix          <- AND Action
/ ( AND | NOT )? Suffix
Suffix          <- Primary ( QUERY / STAR / PLUS )?
Primary         <- Identifier !LEFTARROW
/ OPEN Expression CLOSE
/ Literal
/ Class
/ DOT
/ Action
/ BEGIN
/ END

Identifier      <- < IdentStart IdentCont* > Spacing
IdentStart      <- [a-zA-Z_]
IdentCont       <- IdentStart / [0-9]
Literal         <- ['] < ( !['] Char  )* > ['] Spacing
/ ["] < ( !["] Char  )* > ["] Spacing
Class           <- '[' < ( !']' Range )* > ']' Spacing
Range           <- Char '-' Char / Char
Char            <- '\\' [abefnrtv'"\[\]\\]
/ '\\' [0-3][0-7][0-7]
/ '\\' [0-7][0-7]?
/ '\\' '-'
/ !'\\' .
LEFTARROW       <- '<-' Spacing
SLASH           <- '/' Spacing
AND             <- '&' Spacing
NOT             <- '!' Spacing
QUERY           <- '?' Spacing
STAR            <- '*' Spacing
PLUS            <- '+' Spacing
OPEN            <- '(' Spacing
CLOSE           <- ')' Spacing
DOT             <- '.' Spacing
Spacing         <- ( Space / Comment )*
Comment         <- '#' ( !EndOfLine . )* EndOfLine
Space           <- ' ' / '\t' / EndOfLine
EndOfLine       <- '\r\n' / '\n' / '\r'
EndOfFile       <- !.
Action          <- '{' < [^}]* > '}' Spacing
BEGIN           <- '<' Spacing
END             <- '>' Spacing

Starting with this:

Grammar         <- Spacing Identifier+ EndOfFile
Spacing         <- ( Space / Comment )*
Space           <- ' ' / '\t' / EndOfLine
Comment         <- ';;' ( !EndOfLine . )* EndOfLine
EndOfLine       <- '\r\n' / '\n' / '\r'
EndOfFile       <- !.

Identifier      <- < IdentStart IdentCont* > Spacing    { printf("ID: %s\n", yytext); }
IdentStart      <- [a-zA-Z_]
IdentCont       <- IdentStart / [0-9]

Which doesn't do anything..  I guess I'm not getting
something... Maybe what I need is leg instead of peg?  Indeed, it
seems to support expressions.

exampeles/calc.leg:

%{
#include <stdio.h>
int vars[26];
%}

Stmt	= - e:Expr EOL			{ printf("%d\n", e); }
| ( !EOL . )* EOL		{ printf("error\n"); }

Expr	= i:ID ASSIGN s:Sum		{ \$\$= vars[i]= s; }
| s:Sum				{ \$\$= s; }

Sum	= l:Product
( PLUS  r:Product	{ l += r; }
| MINUS r:Product	{ l -= r; }
)*			{ \$\$= l; }

Product	= l:Value
( TIMES  r:Value	{ l *= r; }
| DIVIDE r:Value	{ l /= r; }
)*			{ \$\$= l; }

Value	= i:NUMBER			{ \$\$= atoi(yytext); }
| i:ID !ASSIGN			{ \$\$= vars[i]; }
| OPEN i:Expr CLOSE		{ \$\$= i; }

NUMBER	= < [0-9]+ >	-		{ \$\$= atoi(yytext); }
ID	= < [a-z]  >	-		{ \$\$= yytext[0] - 'a'; }
ASSIGN	= '='		-
PLUS	= '+'		-
MINUS	= '-'		-
TIMES	= '*'		-
DIVIDE	= '/'		-
OPEN	= '('		-
CLOSE	= ')'		-

-	= [ \t]*
EOL	= '\n' | '\r\n' | '\r' | ';'

%%

int main()
{
while (yyparse());

return 0;
}

One problem though: it doesn't seem to be possible to pass context
into yyparse that can trickle down to the actions.  Makes me wonder
how one would implement dynamic scope in C in a thread-safe way.  I
`[Reply][About]`
`[<<][libprim][>>][..]`