VOOZH about

URL: https://deepwiki.com/netgen/query-translator/3.3-error-handling-and-corrections

⇱ Error Handling and Corrections | netgen/query-translator | DeepWiki


Loading...
Menu

Error Handling and Corrections

Purpose and Scope

This document describes the error handling and correction mechanisms in the QueryTranslator library. One of the core design principles of the Galach query language implementation is that no input is considered invalid. Both the Tokenizer and Parser components are designed to be resilient to errors and will attempt to process any input by applying appropriate corrections when necessary.

This page explains how errors are detected, how corrections are applied during parsing, and how you can access and utilize correction information in your application. For information about the Parser component itself, see Parser.

Error Handling Philosophy


The QueryTranslator library is designed with a robust error handling mechanism that follows a key principle: no input is considered invalid. Instead of rejecting malformed queries with error messages, the system applies corrections to make the query processable. This approach provides several benefits:

  1. Users can enter imperfect queries and still get results
  2. The system can suggest corrections to help users understand proper syntax
  3. Applications can provide visual feedback about corrections

Sources: lib/Languages/Galach/README.md114-120

Correction Workflow


The error handling workflow consists of two main stages:

  1. Tokenization stage: When the Tokenizer encounters characters it cannot parse (such as an unclosed quote), it creates a special TOKEN_BAILOUT token.

  2. Parsing stage: The Parser applies corrections when it encounters problems like missing operands, unmatched brackets, or invalid operator combinations.

All corrections are recorded with a specific type constant and the tokens affected by the correction. These corrections are then stored in the resulting SyntaxTree object, making them available to the application.

Sources: lib/Languages/Galach/README.md114-126 lib/Languages/Galach/Parser.php156-157 lib/Languages/Galach/Parser.php640-642

Correction Types

The Parser defines several correction type constants that identify specific errors that can occur during parsing:

ConstantValueDescriptionExample
CORRECTION_ADJACENT_UNARY_OPERATOR_PRECEDING_OPERATOR_IGNORED0Adjacent unary operator before another operator is ignored++one+one
CORRECTION_UNARY_OPERATOR_MISSING_OPERAND_IGNORED1Unary operator with no operand is ignoredone NOTone
CORRECTION_BINARY_OPERATOR_MISSING_LEFT_OPERAND_IGNORED2Binary operator with no left operand is ignoredAND twotwo
CORRECTION_BINARY_OPERATOR_MISSING_RIGHT_OPERAND_IGNORED3Binary operator with no right operand is ignoredone ANDone
CORRECTION_BINARY_OPERATOR_FOLLOWING_OPERATOR_IGNORED4Binary operator after another operator is ignoredone AND OR twoone two
CORRECTION_LOGICAL_NOT_OPERATORS_PRECEDING_PREFERENCE_IGNORED5Logical NOT before +/- is ignoredNOT +one+one
CORRECTION_EMPTY_GROUP_IGNORED6Empty group is ignoredone () twoone two
CORRECTION_UNMATCHED_GROUP_LEFT_DELIMITER_IGNORED7Unmatched left parenthesis is ignoredone (one
CORRECTION_UNMATCHED_GROUP_RIGHT_DELIMITER_IGNORED8Unmatched right parenthesis is ignoredone )one
CORRECTION_BAILOUT_TOKEN_IGNORED9Bailout token is ignoredone " twoone two

Sources: lib/Languages/Galach/Parser.php28-76 lib/Languages/Galach/README.md130-239

Correction Implementation

Class Structure Diagram


The error handling mechanism is implemented through the following components:

Correction Value Object

The Correction class lib/Values/Correction.php1-39 is a simple value object that stores:

Parser Correction Tracking

The Parser class lib/Languages/Galach/Parser.php24 maintains correction state:

SyntaxTree Correction Storage

The SyntaxTree object stores corrections alongside the parsed tree, making them available for:

  • UI feedback (syntax highlighting, error messages)
  • Query analysis and validation
  • User education about proper syntax

Sources: lib/Values/Correction.php1-39 lib/Languages/Galach/Parser.php24-174 lib/Languages/Galach/Parser.php640-643

Error Handling Mechanisms

The Parser implements specific error handling mechanisms through shift and reduce methods. Each mechanism detects errors during parsing and applies corrections automatically.

Correction Application Flow


Sources: lib/Languages/Galach/Parser.php159-174 lib/Languages/Galach/Parser.php176-207

1. Adjacent Unary Operator Correction

Detection: shiftAdjacentUnaryOperator() lib/Languages/Galach/Parser.php224-236 checks if the next token is an operator when shifting a unary operator.

Applied by:

Correction: CORRECTION_ADJACENT_UNARY_OPERATOR_PRECEDING_OPERATOR_IGNORED (type 0)

Implementation:

if (isToken(nextToken, operatorMask)) {
 addCorrection(CORRECTION_ADJACENT_UNARY_OPERATOR_PRECEDING_OPERATOR_IGNORED, token)
 return null // Don't push token to stack
}

Example: ++one → first + is ignored, produces +one

Sources: lib/Languages/Galach/Parser.php219-248 tests/Galach/IntegrationTest.php1463-1485

2. Unary Operator Missing Operand

Detection: Multiple locations detect unary operators without operands:

Correction: CORRECTION_UNARY_OPERATOR_MISSING_OPERAND_IGNORED (type 1)

Implementation:

if (isTopStackToken(operatorPrefix)) {
 addCorrection(CORRECTION_UNARY_OPERATOR_MISSING_OPERAND_IGNORED, stack->pop())
}

Example: one NOTNOT is ignored, produces one

Sources: lib/Languages/Galach/Parser.php209-217 lib/Languages/Galach/Parser.php530-546 tests/Galach/IntegrationTest.php1202-1224

3. Binary Operator Missing Left Operand

Detection: shiftBinaryOperator() lib/Languages/Galach/Parser.php250-268 checks if stack is empty or top is TOKEN_GROUP_BEGIN.

Correction: CORRECTION_BINARY_OPERATOR_MISSING_LEFT_OPERAND_IGNORED (type 2)

Implementation:

if (stack->isEmpty() || isTopStackToken(TOKEN_GROUP_BEGIN)) {
 addCorrection(CORRECTION_BINARY_OPERATOR_MISSING_LEFT_OPERAND_IGNORED, token)
 return null
}

Example: AND oneAND is ignored, produces one

Sources: lib/Languages/Galach/Parser.php250-268 tests/Galach/IntegrationTest.php1088-1108

4. Binary Operator Missing Right Operand

Detection: popTokens() lib/Languages/Galach/Parser.php530-546 at end of parsing detects binary operators on stack.

Correction: CORRECTION_BINARY_OPERATOR_MISSING_RIGHT_OPERAND_IGNORED (type 3)

Implementation:

while (isTopStackToken(operatorBinary)) {
 token = stack->pop()
 addCorrection(CORRECTION_BINARY_OPERATOR_MISSING_RIGHT_OPERAND_IGNORED, token)
}

Example: one ANDAND is ignored, produces one

Sources: lib/Languages/Galach/Parser.php530-546 tests/Galach/IntegrationTest.php1066-1086

5. Binary Operator Following Operator

Detection: shiftBinaryOperator() lib/Languages/Galach/Parser.php250-268 detects when top of stack is an operator.

Correction: CORRECTION_BINARY_OPERATOR_FOLLOWING_OPERATOR_IGNORED (type 4)

Implementation: ignoreBinaryOperatorFollowingOperator() lib/Languages/Galach/Parser.php270-283

precedingOperators = ignorePrecedingOperators(operator)
followingOperators = ignoreFollowingOperators()
addCorrection(CORRECTION_BINARY_OPERATOR_FOLLOWING_OPERATOR_IGNORED, 
 ...precedingOperators, token, ...followingOperators)

Example: one AND OR twoAND OR are ignored, produces one two

Sources: lib/Languages/Galach/Parser.php270-283 lib/Languages/Galach/Parser.php548-570 tests/Galach/IntegrationTest.php1110-1131

6. Logical NOT Before Preference Operator

Detection: reduceLogicalNot() lib/Languages/Galach/Parser.php322-335 checks if operand is Mandatory or Prohibited.

Correction: CORRECTION_LOGICAL_NOT_OPERATORS_PRECEDING_PREFERENCE_IGNORED (type 5)

Implementation: ignoreLogicalNotOperatorsPrecedingPreferenceOperator() lib/Languages/Galach/Parser.php337-347

if (node instanceof Mandatory || node instanceof Prohibited) {
 precedingOperators = ignorePrecedingOperators(operatorNot)
 if (!empty(precedingOperators)) {
 addCorrection(CORRECTION_LOGICAL_NOT_OPERATORS_PRECEDING_PREFERENCE_IGNORED, 
 ...precedingOperators)
 }
 return node // Don't wrap in LogicalNot
}

Example: NOT +oneNOT is ignored, produces +one

Sources: lib/Languages/Galach/Parser.php322-347 tests/Galach/IntegrationTest.php1418-1440

7. Empty Group Ignored

Detection: reduceGroup() lib/Languages/Galach/Parser.php393-415 checks if left delimiter immediately followed by right delimiter.

Correction: CORRECTION_EMPTY_GROUP_IGNORED (type 6)

Implementation: ignoreEmptyGroup() lib/Languages/Galach/Parser.php433-446

if (isTopStackToken(TOKEN_GROUP_BEGIN)) {
 leftDelimiter = stack->pop()
 precedingOperators = ignorePrecedingOperators(operator)
 followingOperators = ignoreFollowingOperators()
 addCorrection(CORRECTION_EMPTY_GROUP_IGNORED,
 ...precedingOperators, leftDelimiter, rightDelimiter, ...followingOperators)
 return null
}

Example: one () two() is ignored, produces one two

Sources: lib/Languages/Galach/Parser.php393-446 tests/Galach/IntegrationTest.php1487-1509

8. Unmatched Group Left Delimiter

Detection: cleanupGroupDelimiters() lib/Languages/Galach/Parser.php592-613 preprocesses tokens before parsing.

Correction: CORRECTION_UNMATCHED_GROUP_LEFT_DELIMITER_IGNORED (type 7)

Implementation: Uses getUnmatchedGroupDelimiterIndexes() lib/Languages/Galach/Parser.php615-638 to find unmatched delimiters.

indexes = getUnmatchedGroupDelimiterIndexes(tokens)
for each index in indexes (reverse order):
 token = tokens[index]
 unset(tokens[index])
 if (token->type === TOKEN_GROUP_BEGIN) {
 addCorrection(CORRECTION_UNMATCHED_GROUP_LEFT_DELIMITER_IGNORED, token)
 }

Example: one (two( is removed, produces one two

Sources: lib/Languages/Galach/Parser.php592-638 tests/Galach/IntegrationTest.php1511-1533

9. Unmatched Group Right Delimiter

Detection: Same as correction type 7, but for right delimiters.

Correction: CORRECTION_UNMATCHED_GROUP_RIGHT_DELIMITER_IGNORED (type 8)

Implementation: Part of cleanupGroupDelimiters() lib/Languages/Galach/Parser.php592-613

if (token->type === TOKEN_GROUP_END) {
 addCorrection(CORRECTION_UNMATCHED_GROUP_RIGHT_DELIMITER_IGNORED, token)
}

Example: one two)) is removed, produces one two

Sources: lib/Languages/Galach/Parser.php592-613 tests/Galach/IntegrationTest.php1535-1557

10. Bailout Token Ignored

Detection: shiftBailout() lib/Languages/Galach/Parser.php302-305 handles TOKEN_BAILOUT tokens created by tokenizer.

Correction: CORRECTION_BAILOUT_TOKEN_IGNORED (type 9)

Implementation:

protected function shiftBailout(Token $token) {
 addCorrection(CORRECTION_BAILOUT_TOKEN_IGNORED, token)
}

Example: one " (unclosed quote) → " is ignored, produces one

Sources: lib/Languages/Galach/Parser.php302-305 tests/Galach/IntegrationTest.php1049-1064

Accessing Correction Information

Correction Data Structure

The SyntaxTree object returned by Parser::parse() lib/Languages/Galach/Parser.php159-174 contains a public $corrections array. Each Correction object provides:

PropertyTypeDescription
$typeintOne of the 10 correction constants (0-9)
$tokensToken[]Array of tokens affected by the correction

Accessing Corrections


Use Cases for Correction Information

1. Syntax Highlighting

Use token positions to highlight problematic query parts:


2. Error Messages

Generate user-friendly error messages:


3. Query Validation

Check if query has specific types of errors:


4. Corrected Query Generation

The original query can be reconstructed from $syntaxTree->tokenSequence->source, while the corrected version can be generated using the Native generator. Comparing these shows what was changed.

Sources: lib/Values/Correction.php1-39 lib/Values/SyntaxTree.php lib/Languages/Galach/Parser.php159-174

Integration with Query Processing Pipeline


The error handling and correction system is tightly integrated with the overall query processing pipeline:

  1. The Tokenizer performs initial lexical analysis and marks problematic tokens
  2. The Parser applies corrections during syntax analysis
  3. All corrections are stored in the SyntaxTree
  4. Applications can access these corrections to provide feedback
  5. The Generator produces valid backend queries from the corrected syntax tree

This design ensures that even imperfect queries can be processed meaningfully, providing a better user experience.

Sources: lib/Languages/Galach/README.md32-42 lib/Languages/Galach/Parser.php157-173

Summary

The error handling and correction system in QueryTranslator is designed to make the query parsing process resilient to errors. Instead of failing on invalid input, the system applies corrections and continues processing. This approach provides several benefits:

  1. Robustness: The system can handle a wide variety of input, even if it contains syntax errors.
  2. User-friendliness: Users don't need to know the exact syntax to get results.
  3. Feedback: Applications can provide helpful feedback about corrections.

The correction mechanism is implemented through the Correction class, which stores information about each correction applied during parsing. These corrections are then made available through the SyntaxTree object, allowing applications to access and use them as needed.

Sources: lib/Languages/Galach/README.md114-240 lib/Values/Correction.php1-39

Refresh this wiki

On this page