#! /usr/bin/python import sys def parse_string(token_array): END = 0; # EOL (end of line) token. LIT = 1; # Literal token. PLUS = 2; # Addition operator token. TIMES = 3; # Multiplication operator token. # Loop through token array for syntax check. for i in range(0,len(token_array)): # If we're on the first token of the line, check to make sure the first token # is a literal. Lines cannot begin with a PLUS, TIMES, or END, unless the end # symbol is say...a newline...at which point maybe END should be allowed? For # now however, it isn't. This is also nice to have as an early escape. if i == 0: # If the first token isn't 1 (LIT)... if locals()[(token_array[i])] != 1: # ...throw an error at the user (not at the head!)... print("Error: Line must begin with literal."); # ...then die badly. sys.exit(1); else: # So that it's delcared, just not AS anything, that comes later. previous_token = ""; # If this is the final token, and it isn't an END, we die right away and notify # the user of this error, as well as reporting the final token type. if locals()[(token_array[len(token_array)-1])] != 0 : print("Error: This line doesn't appear to end in an END (0). Dying."); sys.exit(1); # This will check for consecutive matches or two tokens in a row. This should # not happen at the moment, as in this example, having two or more consecutive # matches should be impossible. #if i > 0 and locals()[(token_array[i])] == previous_token: # # Notify the user of the impending impossibility...or rather...improbability? # print("Error: Two consecutive matching tokens. This is, for the moment, impossible."); # # Die badly. # sys.exit(1); # Check if token is END. if locals()[(token_array[i])] == 0: # Print if an END is found. print("Okay: Found END."); # In most languages, you would continue on a line even if you encounter # a mid-line END, however for the sake of parsing a single line, lets not # do that for now. break; # Check if token is LIT. if locals()[(token_array[i])] == 1: print("Okay: Found LIT."); # If the previous token was a literal too, then this is disallowed for # the time being, throw an error because of the consecutive literals. if locals()[(token_array[i])] == 1 and previous_token == 1: print("Error: Two literals in a row. Stray space perhaps?"); sys.exit(1); # Check if token is PLUS. if locals()[(token_array[i])] == 2: print("Okay: Found PLUS."); if previous_token == 1 and locals()[(token_array[i+1])] == 1: print("Okay: Valid addition between two literals."); else: print("Error: Attempt to add tokens of type "+str(previous_token)+" and type "+str(locals()[(token_array[i+1])])+". These are incompatible."); sys.exit(1); # Check if token is TIMES. if locals()[(token_array[i])] == 3: print("Okay: Found TIMES."); if previous_token == 1 and locals()[(token_array[i+1])] == 1: print("Okay: Valid multiplication between two literals."); else: print("Error: Attempt to multiply tokens of type "+str(previous_token)+" and type "+str(locals()[(token_array[i+1])])+". These are incompatible."); sys.exit(1); # It would be useful to take note of the token after we're done parsing it so # that we can compare what should be next depending upon the previous token # so as to catch syntax errors. Token is stored as an integer. previous_token = locals()[(token_array[i])]; print("Okay: Previous token: "+str(previous_token)); # If you've made it to this point, then that means that no errors of a major kind # have been caught above, and you're probably safe to start generating trees from # the given token lines. print("Okay: All clear."); return 0; if __name__ == "__main__": # An array of correctly ordered strings. string_correct = ["LIT","PLUS","LIT","TIMES","LIT","END"]; #string_incorrect = ["LIT","PLUS","LIT","TIMES","END"]; #string_incorrect_begin = ["PLUS","LIT","END"]; #string_incorrect_no_end = ["LIT","PLUS","LIT"]; parse_string(string_correct); #parse_string(string_incorrect); #parse_string(string_incorrect_begin); #parse_string(string_incorrect_no_end);