Jump to content
xisto Community
vizskywalker

Find An Unmatched Ending Parenthesis

Recommended Posts

I'm creating a parser (a small compiler really) and I need to be able to find an unmatched ending parenthesis, the first one, in a string. By unmatched I mean in that string there is no opening parenthesis for that ending parenthesis. Any suggestions would be helpful.~Viz

Share this post


Link to post
Share on other sites

Assuming that you are trying to debug a piece of code that is giving errors here is what I do.
When I lose a parenthesis or bracket, I usually end up printing out the code to paper and number each set.

Starting with the code (example only):

((()()((()))()()(()()(()())()()(())))()()

I write a number next to each opening parenthesis and the same number next to th corresponding closing parenthesis like so:
(1 (2 (3 )3 (4 )4 (5 (6 (7 )7 )6 )5 (8 )8 (9 )9 (10 (11 )11 (12 )12 (13 (14 )14 (15 )15 )13 (16 )16 (17 )17 (18 (19 )18 )17 )16 (20 )20 (21 )21

I think that leaves me with the following unclosed parenthesis:
1, 2, 10, 19

Now that usually gives me enough information to find the problem.

If that doesn't do the trick, I have to break the string up into it's individual parts.

Imagine I have the following nested functions:
function_1(function_2(function_3(function_4() . function_5(function_6()) . function_7(function_8(function_9()))) . function_10(function_11())) . function_12(function_13(function_14(function_15())) . function_16()));

You'd have to assign variables to each function and rewrite the code like so:
$f6 = function_6();$f9 = function_9();$f8 = function_8($f9);$f7 = function_7($f8);$f5 = function_5($f6);$f4 = function_4();$f3 = function_3($f4 . $f5 . $f7);$f11 = function_11();$f10 = function_10($f11);$f2 = function_2($f3 . $f10);$f15 = function_15();$f14 = function_14($f15);$f13 = function_13($f14);$f16 = function_16();$f12 = function_12($f13 . $f16);function_1($f2 . $f12)

Of course, here all of the parenthesis were paired correctly. Assigning each function it's own variable and writing the same code vertically instead of horizontally won't show which parenthesis is missing/extra but by evaluating each variable, you should be able to locate any errors.

I suppose that you could write a script that would convert your nested functions into a multi-line code.

If you are trying to add code to your parser (mini-compiler) to identify when there is a missing/extra parenthesis, I'd read the code line by line and and increment a counter every time an opening parenthesis is found and do the same for each closing parenthesis that is found. The compare $open to $close. If not the same generate an error message. This will only give you the line number of the error which is about as much as most parser will do for you. The error message could tell you if there are more opening or closing parenthesis.

Since most code is written with parenthesis opening and closing on the same line, this would work. If you expect the code to wrap several lines without closing, then you'll need to break the code down to statements instead of lines. Instead of using the new line as the limit at which a parenthesis is terminated, you should use the semi-colon. You should still note the line number that the statement started on.

If you read your code as a file and broke it down into an array with explode(";", $file_contents), then you can more easily keep track of each statement.

I guess a lot of this kind of depends on the code that is being parsed.

Well, hope this helps a little.

vujsa

Share this post


Link to post
Share on other sites

Get an editor that has highlighting for your syntax. PHP Designer is a good editor and has this capability. and you can define the color of opening and closing characters. I use cyan for my dolor but I believe that as a default PHP Designer comes using yellow as the color.

 

The best way to check for an unmatched parenthesis or curly brace or square bracket is to place you cursor to the immediate left of the character inquestion. The character most likely to be missing though is the closing curly brace }in a if or else block of code. Which will give the error of

 

Parse error: syntax error, unexpected $end in D:\Program Files\xampp\htdocs\NewsPortalProject\register.php on line 42

 

The above is just an example but one like it will come up when you leave a curly brace off in your code. At PHP builder and Dev Shed and PHP Phreaks you will see someone complaining about this very often, and of course the standard answer is that you have left a curly brace out of your code. The error almost always point to the line after the end of your code also. If you got the above error it is most likely that your code is actually only 41 lines long which confuses most beginners.

 

This is why I use PHP Designer's auto completion feature, which at time can be annoying with single quotes but saves me from the problems of unmatched braces or parenthesis and so on. If you do not have aPHP Designer then you can download it here at http://www.mpsoftware.dk/phpdesigner.php You will speed up your development and debugging tremendously using such a tool.

 

This is not an advertisement for PHP Designer mostly because it is FREEWARE, but because it is a really great program for the price of merely downloading it. I used to use HTML Kit and still do but for development purposes I use PHP Designer.

 

Usually in the case of a parenthesis it should be possible to find the error because they are used mostly with functions with little or even nothing between them such as mail() function which has no more than 5 parameters, two are optional, and each are seperated by commas so if you had a problem with the below

mail "toemail@asite.com","Surprise E-mail", 'My Subject', $message);
of course this error would be easy to locate since it is so short, actually you should not have too much trouble finding a missing parenthesis, but a curly brace is a different story. Do your self a favor and get a good editor and I do not care what anyone else says about using notepad or whatever Macs editor is or the editor that come with Linux, get a good editor that actually helps you write and trouble shoot code.

Share this post


Link to post
Share on other sites

Okay, I guess I could have been a lot more clear, but I was in a rush when I made this initial post. So here comes the big explanation:

I am designing a game which has a PHP written "processor". This processor script takes programs in "machine code" (a language I made up) and runs the programs. (The processor script has yet to be written). Now, players are allowed to write their own programs using the language I made up, except they use the "compiler" I'm writing to turn it into the "machine code" so the "processor" can run it.

The problem is not in code I've written, and I'm not looking for a lost parenthesis, just the end of an already open group.

The compiler runs through each line of code various times, and for certain lines you can have more than one function per line as in the example:

CX=AX-BX+1
Now, after the first run through, the "=" operator has been handled and the partially compiled code looks like such:
MOV(CX)(AX-BX+1)
Due to the nature of the language, after the first partial compile, it would be possible to have a function inside of one of the parenthesis, like so:
MOV(CX)(AX-BX+1+GetStart())
However, because certain lines can get complex, there could be numerous groupings of parenthesis, and when parsing an operator, like the "=" operator, I need to only grab the code to the first unmatched parenthesis and not the entire remaining line of code.

I found my own solution which is actually pretty simple:
$closecount = 0;  $currentpos = strpos($code, ')');  $opencount = substr_count($code, '(', 0, $currentpos);  $length = $currentpos - 1;    while (($opencount - $closecount) >= 0) {      $closecount++;   $currentpos = strpos($code, ')', $currentpos + 1);   if ($currentpos) {		$opencount = substr_count($code, '(', 0, $currentpos);	$length = $currentpos - 1;	   }   else {		$length = strlen($code);	break;	   }     }    return substr($code, 0, $length);
What this code does is find the first ")" and then count the number of "(" that come before it. If there are more "(" than ")", it finds the next ")", adds 1 to the number of ")" and repeats the check.

I have hit a new problem however, where I need to grab a piece of the string holding a line of code to the left of an operator until an operator is reached, an unmatched open parenthesis is reached, or the beginning of the line is reached. Similarly, I need to perform the same sort of grab to the right, only this time with an unmatched closing parenthesis. I think a method similar to what I am doing should work, but your ideas will be helpful as well.

~Viz

Share this post


Link to post
Share on other sites

Use stack man - that's how they do it normally. Push every paranthesis you can find and for every closing one you find, pop one. But to locate it exactly, umm... lemme think about it a bit. Might be able to do it using a combination of stack and hashtables.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.