Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7759931
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T13:45:05+00:00 2026-06-01T13:45:05+00:00

How should I use callback functions in parsekit? suppose I have the following rule:

  • 0

How should I use callback functions in parsekit? suppose I have the following rule:

expr_s = expr_p '+' expr_s | expr_p ; 

should I pop 3 symbols from the resulting PKAssembly and add first and last numbers and then push the answer back to the stack?
And for the above rule how should I know it is the first or the second rule that caused a match?
I don’t understand the order in which ParseKit calls callback functions. I could really use some help.

Thanks Todd for your response, keeping in mind your instructions I wrote the following grammar and callback functions for a simple mathematics expression that includes addition and multiplication:

- (IBAction)press_equals:(id)sender {
NSString *g = @"@start = expr_s; expr_s = expr_p ('+'! expr_p)+ ; expr_p = Number ('*'!     Number)+  ;";
PKParser *p = [[PKParserFactory factory] parserFromGrammar:g assembler:self];
NSString *s = @"3*4+4*8";

[p parse:s];

PKAssembly *res = [p parse:s];
NSLog(@"res %@", res);

}



- (void)parser:(PKParser *)p didMatchExpr_s:(PKAssembly *)a {
NSLog(@"%s %@", __PRETTY_FUNCTION__, a);

NSArray *toks = [a objectsAbove:nil];


double total = 0.0;
for (PKToken *tok in toks) {
    total += tok.floatValue;
}


a.target = [NSNumber numberWithDouble:total];
}
- (void)parser:(PKParser *)p didMatchExpr_p:(PKAssembly *)a {
NSLog(@"%s %@", __PRETTY_FUNCTION__, a);

NSArray *toks = [a objectsAbove:nil];


double total = 1.0;
for (PKToken *tok in toks) {
    total *= tok.floatValue;
}
a.target = [NSNumber numberWithDouble:total];
}

and here is the output I get:

2012-04-06 22:54:31.975 Calculator[1070:207] -[CalculatorViewController    parser:didMatchExpr_p:] [3, 4]3/*/4^+/4/*/8
2012-04-06 22:54:31.976 Calculator[1070:207] -[CalculatorViewController parser:didMatchExpr_p:] [4, 8]3/*/4/+/4/*/8^
2012-04-06 22:54:31.977 Calculator[1070:207] -[CalculatorViewController parser:didMatchExpr_s:] []3/*/4/+/4/*/8^
2012-04-06 22:54:31.977 Calculator[1070:207] -[CalculatorViewController parser:didMatchExpr_p:] [3, 4]3/*/4^+/4/*/8
2012-04-06 22:54:31.978 Calculator[1070:207] -[CalculatorViewController parser:didMatchExpr_p:] [4, 8]3/*/4/+/4/*/8^
2012-04-06 22:54:31.978 Calculator[1070:207] -[CalculatorViewController parser:didMatchExpr_s:] []3/*/4/+/4/*/8^
2012-04-06 22:54:31.979 Calculator[1070:207] res 0

Why is my res 0?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T13:45:06+00:00Added an answer on June 1, 2026 at 1:45 pm

    Developer of ParseKit here.

    First, the best way to understand this stuff is Steven Metsker’s book, upon which ParseKit is based.


    Second, checkout my answer to another question about PKAssembly‘s stack and target.


    Third, here’s my answer to another PaseKit question about unexpected callbacks.


    Fourth, checkout the TDArithmeticParser.m file in the the ParseKit Tests Target (included in the ParseKit Xcode project. This class has callbacks which implement the same kind of arithmetic logic you seem to be looking for.

    Also checkout the arithmetic.grammar file (also in the ParseKit Tests Target). This is an example of how to design an arithmetic grammar in ParseKit syntax.


    Finally, here’s some thoughts more specific to your example above.

    Let’s clarify your grammar a bit, as the question you’re asking is pretty basic, and I don’t think it requires a very complex grammar to tackle. Here’s a basic arithmetic grammar which gives multiplication and division operators precedence over addition and subtraction:

    @start         = expr;
    expr           = term (plusTerm | minusTerm)*;
    term           = factor (timesFactor | divFactor)*;
    plusTerm       = '+'! term;
    minusTerm      = '-'! term;
    timesFactor    = '*'! factor;
    divFactor      = '/'! factor;
    factor         = Number;
    

    That ! after the '+' tells ParseKit to discard this token automatically. This makes things slightly more convenient for you when writing your callbacks.

    Note that if you want your grammar to have only left-to-right operator precedence (like a calculator), this grammar will not work. If you need that, please ask a separate question tagged #ParseKit here on StackOverflow, and I will answer it promptly.

    I would define these callbacks:

    - (void)parser:(PKParser *)p didMatchExpr:(PKAssembly *)a {
        NSLog(@"%s %@", __PRETTY_FUNCTION__, a);
    
        NSNumber *n = [a pop];
    
        // the expr is complete, and its value is on the stack.
        // important! wrap things up by 
        // storing your work in `a.target`. not in an ivar.
        a.target = n;
    }
    
    - (void)parser:(PKParser *)p didMatchFactor:(PKAssembly *)a {
        NSLog(@"%s %@", __PRETTY_FUNCTION__, a);
    
        // a number token was found. store its number value on the stack
        PKToken *tok = [a pop];
        [a push:[NSNumber numberWithDouble:tok.floatValue]];
    }
    
    - (void)parser:(PKParser *)p didMatchPlusTerm:(PKAssembly *)a {
        NSLog(@"%s %@", __PRETTY_FUNCTION__, a);
    
        // a '+' expr was found. pop off the two operands and add them
        // store the result on the stack temporarily
        NSNumber *n2 = [a pop];
        NSNumber *n1 = [a pop];
        [a push:[NSNumber numberWithDouble:[n1 doubleValue] + [n2 doubleValue]]];
    }
    
    - (void)parser:(PKParser *)p didMatchMinusTerm:(PKAssembly *)a {
        NSLog(@"%s %@", __PRETTY_FUNCTION__, a);
    
        // a '-' expr was found. pop off the two operands and subtract them
        // store the result on the stack temporarily
        NSNumber *n2 = [a pop];
        NSNumber *n1 = [a pop];
        [a push:[NSNumber numberWithDouble:[n1 doubleValue] - [n2 doubleValue]]];
    }
    
    - (void)parser:(PKParser *)p didMatchTimesFactor:(PKAssembly *)a {
        NSLog(@"%s %@", __PRETTY_FUNCTION__, a);
    
        // a '*' expr was found. pop off the two operands and multiply them
        // store the result on the stack temporarily
        NSNumber *n2 = [a pop];
        NSNumber *n1 = [a pop];
        [a push:[NSNumber numberWithDouble:[n1 doubleValue] * [n2 doubleValue]]];
    }
    
    - (void)parser:(PKParser *)p didMatchDivideFactor:(PKAssembly *)a {
        NSLog(@"%s %@", __PRETTY_FUNCTION__, a);
    
        // a '/' expr was found. pop off the two operands and divide them
        // store the result on the stack temporarily
        NSNumber *n2 = [a pop];
        NSNumber *n1 = [a pop];
        [a push:[NSNumber numberWithDouble:[n1 doubleValue] / [n2 doubleValue]]];
    }
    

    Two important points are

    1. Don’t worry about how many times these callbacks are called. They may be called more times than you expect, or in strange-seeming order.
    2. Don’t store the results of work done in these callbacks in an ivar. Always store your work on either the a argument’s target or stack. I usually store temporary values on the stack, and the ultimate result on the target, as I find that most convenient. But you have flexibility there.

    I would write this driver code:

    NSString *g = .. // fetch grammar above
    PKParser *p = [[PKParserFactory factory] parserFromGrammar:g assembler:self];
    NSString *s = @"3*4+4*8";
    
    PKAssembly *res = [p parse:s];
    NSLog(@"res %@", res);
    

    I see this log output:

    -[DebugAppDelegate parser:didMatchFactor:] [3]3^*/4/+/4/*/8
    -[DebugAppDelegate parser:didMatchFactor:] [3, 4]3/*/4^+/4/*/8
    -[DebugAppDelegate parser:didMatchTimesFactor:] [3, 4]3/*/4^+/4/*/8
    -[DebugAppDelegate parser:didMatchFactor:] [12, 4]3/*/4/+/4^*/8
    -[DebugAppDelegate parser:didMatchFactor:] [12, 4, 8]3/*/4/+/4/*/8^
    -[DebugAppDelegate parser:didMatchTimesFactor:] [12, 4, 8]3/*/4/+/4/*/8^
    -[DebugAppDelegate parser:didMatchPlusTerm:] [12, 4]3/*/4/+/4^*/8
    -[DebugAppDelegate parser:didMatchPlusTerm:] [12, 32]3/*/4/+/4/*/8^
    -[DebugAppDelegate parser:didMatchExpr:] [3]3^*/4/+/4/*/8
    -[DebugAppDelegate parser:didMatchExpr:] [12]3/*/4^+/4/*/8
    -[DebugAppDelegate parser:didMatchExpr:] [16]3/*/4/+/4^*/8
    -[DebugAppDelegate parser:didMatchExpr:] [44]3/*/4/+/4/*/8^
    res 44
    

    Hope this helps.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

What's the best approach/pattern I should use for the following? Have a C# UI
Why sometimes I should use block and other times &block inside functions that accept
I wonder how I should use the GTree (from GLib) to store data? Every
I don't know which title I should use for this question. I have a
I have a partial view need register several event callback functions for it, however
I'm using the hoverIntent Jquery plugin and I have a question regarding callback functions.
I've read I should use money , but in todays fast paced world maybe
I know you should use POST whenever data will be modified on a public
I know you should use a StringBuilder when concatenating strings but I was just
I wonder why I should use: puts In folder #{File.join ENV[HOME], projects} Instead of:

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.