[<<][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
guess by using thread-local variables..

Ok.  I think I get the basic idea.  Now the subtleties.  How to
express delimiting?

[1] http://piumarta.com/software/peg/peg.1.html



[Reply][About]
[<<][libprim][>>][..]