/* a parser that is composed of the previous parsers to get a number out of the input string. * it succeeds iff the input line contains a floating point number. if successful, the result * is given in res, if fails, the error is given in error and return value is NULL.*/ char* getNumber(char*p, float* res, int* err) { char* e; char t; /* do we have anything to work on? */ if (p==NULL || *p == '\0') return NULL; /* a nice trick by using or parser */ e = or(charIs(p, '-'), p); e = allDigits(e); e = or(charIs(e, '.'), e); e = or(allDigits(e), e); /* at the end of the previous 4 lines, we could have numbers in the following format -1, 1, -1. ,1.543, -65.45 */ /* if any of the above parsers had failed, return failure */ if (e == NULL) return e; /* remove leading whitespace */ e = strip(e, " "); /* if after removing all whitespaces we didnt hit either ',', end-of-line, or nothing was consumed at all, * then the input that was given is wrong! fail this parser!*/ if ((!charIs(e, ',') && !charIs(e, '\n'))||e==p) { *err = NUMBER_ERR; return NULL; } /* if everything succeeded up till now, then e points to the rest of the input AFTER the valid float number, * so we use a little trick to make it a float number:*/ t = *e; /* save the end of the consumed string */ *e = '\0'; /* mark it as end of line */ *res = (float)atof(p); /* use atof to transform the original input string (p) into the number */ *e=t; /* set the end of consumed string back to its original value */ return e; /* return the pointer to the rest of the unconsumed string */ }
PrologLexer::PrologLexer() { lexer.rules[Prolog::Spacing] = loop1(charOf(" \t\n\r")); lexer.rules[Prolog::LParen] = str("("); lexer.rules[Prolog::RParen] = str(")"); lexer.rules[Prolog::LBracket] = str("["); lexer.rules[Prolog::RBracket] = str("]"); lexer.rules[Prolog::OnlyIf] = str(":-"); lexer.rules[Prolog::Eq] = str("="); /* lexer.rules[Prolog::Lt] = str("<"); lexer.rules[Prolog::Gt] = str(">"); lexer.rules[Prolog::Le] = str("<="); lexer.rules[Prolog::Ge] = str(">="); lexer.rules[Prolog::Ne] = str("<>"); */ lexer.rules[Prolog::Dot] = str("."); lexer.rules[Prolog::Comma] = str(","); lexer.rules[Prolog::Semi] = str(";"); lexer.rules[Prolog::Bar] = str("|"); lexer.rules[Prolog::DomainsKw] = str("domains"); lexer.rules[Prolog::PredicatesKw] = str("predicates"); lexer.rules[Prolog::ClausesKw] = str("clauses"); lexer.rules[Prolog::AssertKw] = str("assert"); lexer.rules[Prolog::Str] = seq(str("\""), loop(anyBut(choice(str("\""), str("\n")))), str("\"")); shared_ptr<RegExp> digit = charIs([](QChar c) { return c.isDigit(); },"<digit>"); shared_ptr<RegExp> letter = charIs([](QChar c) { return c.isLetter(); }, "<letter>"); shared_ptr<RegExp> smallLetter = charIs([](QChar c) { return c.isLower(); }, "<lowercase>"); shared_ptr<RegExp> capitalLetter = charIs([](QChar c) { return c.isUpper(); }, "<uppercase>"); shared_ptr<RegExp> alpha = charIs([](QChar c) { return c.isLetterOrNumber(); },"<alphanumeric>"); shared_ptr<RegExp> symbol = charOf("+-/*<>="); shared_ptr<RegExp> digits = seq(loop1(digit), checkNo(letter)); shared_ptr<RegExp> smallLetterOrSymbol = choice(smallLetter, symbol); shared_ptr<RegExp> alphaOrUnderscore = choice(alpha, str("_")); shared_ptr<RegExp> alphaOrSymbol= choice(alpha, symbol); lexer.rules[Prolog::Num] = seq(digits, optional(seq(str("."), digits))); lexer.rules[Prolog::Symbol] = seq(smallLetterOrSymbol, loop(choice(digit, alphaOrSymbol))); lexer.rules[Prolog::Variable] = seq(choice(capitalLetter, str("_")), loop(choice(digit, alphaOrUnderscore))); }
/* A helper function for removing newlines, used for error reporting */ char* trimNewline(char* line) { int l = strlen(line); int i=0; if (oneOf(&line[l-1],"\r\n")) { i++; if (charIs(&line[l-2],'\r')) i++; } line[l-i]='\0'; return line; }