The language you're trying to parse now is much more complex than the one in your initial post. You'll soon end up with problems if you keep using your current method of trying to match the entire statement at once. Consider the following.

1) Nested statemements. How will you handle if (...) { if (...) { ... } }?

2) Order of operation. How will you handle a = b + c * d?

3) Error reporting. How can you give a meaningful error message when at best, you only know if a whole statement is valid or not.

Usually, it's not worth the effort to invent a new language. Embedding Perl sounds like a great idea if you're looking for a feature-full language. If you need to restrict access to certain functions, there's a module called "Safe" or "something::Safe" which allows you to do just that.

For fun, what follows is a RecDescent parser for the grammar you had above. (It actually does a little bit more, but I wanted to keep it very close to yours. I could have made it identical, so don't think it's a limitation of the module. I did force assignments to end with semi-colons to simplify the grammar and keep it readable.)

use strict; use warnings; use Data::Dumper (); use Parse::RecDescent (); { my $grammar = <<'__EOI__'; { use strict; use warnings; } # --- Tokens --- EOF : /^\Z/ IDENTIFIER : /[A-Za-z]\w*/ LITERAL : /\d+/ REL_OP : />=?|<=?|==/ EQUAL : '=' # --- Keywords --- IF_KEYWORD : IDENTIFIER { $item[1] eq 'if' ? $item[1] : und +ef } # --- Rules --- parse : stmt(s?) EOF { $item[1] } stmt : IF_KEYWORD <commit> if_rest { [ $item[1], @{$i +tem[3]} ] } | label { $item[1] } | assign ';' { $item[1] } | call ';' { $item[1] } | <error> if_rest : '(' compare ')' '{' stmt(s?) '}' { [ @item[2, + 5] ] } label : IDENTIFIER ':' { [ @item[0, 1] ] } assign : IDENTIFIER EQUAL term { [ @item[2, 1, 3] ] } call : IDENTIFIER { [ @item[0, 1] ] } compare : term REL_OP term { [ @item[2, 1, 3] ] } term : IDENTIFIER { [ 'identifier', $item[1] ] } | LITERAL { [ 'literal', $item[1] ] } __EOI__ $::RD_HINT = 1; # $::RD_TRACE = 1; # Parse::RecDescent::Hack->Precompile($grammar, "Module"); my $parser = Parse::RecDescent->new($grammar); die("Bad grammar.\n") unless defined($parser); my $text = <<'__EOI__'; test: a=4;b =5 ; c = 9; if (b > a) { c = 100; } Camel: Camel = 5; hippo: ilovetoswim; ifthen1: if ( ABC > 500 ){XYZ = 10;} ifthen2: if ( ABC < 500 ){sdfsdf;} ifthen4: if ( ABC == 500 ){sdfsdf;} ifthen7: if ( ABC <= 500 ){sdfsdf;} ifthen8: if ( ABC >= 500 ){sdfsdf;} __EOI__ my $result = $parser->parse(\$text); die("Bad text.\n") unless (defined($result)); print("Parse Tree\n"); print("==========\n"); print Data::Dumper::Dumper($result); }

From here, it's easy to replace compare and assign with expr. And it's pretty simple to expand expr into something that handles numeous operators with varied precedence. Adding while would be trivial.


In reply to Re^5: command input processing by ikegami
in thread command input processing by thekestrel

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.