//=================================================================================================== // // HL.jjt copyright Sophie Quigley 2024 // // The copyright to this original work is held by Sophie Quigley, and students registered in course // CPS710 taught at Toronto Metropolitan University in the Fall semester of 2022 can use this material // for the purposes of this course, but no other use is permitted and there can be no sale or transfer // or use of the work for any other purpose without the explicit permission of Sophie Quigley. // In particular, no part of this file and can be posted in code repositories, or transmitted to // students not registered in CPS710 in the Fall semester of 2024. // //=================================================================================================== options { IGNORE_CASE=false; MULTI=true; // This will generate one AST class for each non-suppressed non-terminal JJTREE_OUTPUT_DIRECTORY="AST"; // This will put all your AST classes in the AST directory VISITOR=true; // This won't be used until the next assignment, but will be needed to make your assignment compile properly } PARSER_BEGIN(HL) public class HL { } PARSER_END(HL) TOKEN_MGR_DECLS : { } SKIP : { " " | "\t" | "\n" | "\r" } TOKEN : { < LESS: "<"> | < LESSEQ: "<="> | < GREATER: ">"> | < GREATEQ: ">="> | < EQUAL: "=="> | < NOTEQ: "!="> | < PLUS: "+"> | < MINUS: "-"> | < TIMES: "*"> | < DIV: "/"> | < MOD: "%"> | < AND: "&"> | < VBAR: "|"> | < NOT: "!"> | < ASSIGN: "="> | < LROUND: "("> | < LCURLY: "{"> | < LSQUARE: "["> | < RROUND: ")"> | < RCURLY: "}"> | < RSQUARE: "]"> | < COMMA: ","> | < SEMICOL: ";"> | < TRUE: "#1"> | < FALSE: "#0"> } TOKEN [IGNORE_CASE]: { < DO:"DO"> | < ELIF:"ELIF"> | < ELSE:"ELSE"> | < END:"END"> | < FI:"FI"> | < FOR:"FOR"> | < FUNCTION:"FUNCTION"> | < IF:"IF"> | < IN:"IN"> | < ISIN: "=IN"> | < NOTIN: "!IN"> | < PRINT:"PRINT"> | < PRINTLN:"PRINTLN"> | < RETURN:"RETURN"> | < THEN:"THEN"> | < VAR:"VAR"> | < WHILE:"WHILE"> } TOKEN : { < #DIGIT: ["0"-"9"]> | < #LOWER: ["a"-"z"]> | < #UPPER: ["A"-"Z"]> | < #LETTER: ["a"-"z","A"-"Z"]> | < NUMBER: ()+ > | < IDNUM: (|)* > | < IDSET: (|)* > | < IDBOOL: "#" (|)* > | < STRING: "\"" (~["\""])* "\"" > } // ---------------------- COMMENTS ---------------------------- SPECIAL_TOKEN : { } //================================================================== // P A R S E R //================================================================== //------------------------ STATEMENTS, BODIES AND CLAUSES ----------------------------------- // ------------------------------- BEGINNING ----------------------------------- SimpleNode start () #void : {} { S() { return (SimpleNode) (jjtree.popNode()); } | < EOF > {throw new ParseException("End of File.");} } void S() throws ParseException : {} { statement_LL1() ";" | LOOKAHEAD(identifier() "=") assign_stat() ";" | expression() ";" } //------------------------ STATEMENTS, BODIES AND CLAUSES ----------------------------------- // These are all the statements which can be differentiated from each other // with a single lookahead void statement_LL1() : {} { var_decl() | fn_decl() | return_stat() | print_stat() | println_stat() | if_stat() | for_stat() | while_stat() } void statement() : {} { statement_LL1() | LOOKAHEAD(2) fn_call() | assign_stat() } void body() : {} { (statement() ";")* } void clause() : {} { (statement() ";")+ } //--------------------------- DECLARATIONS ------------------------------------------------ void var_decl() : {} { ident_list() } void fn_decl() : {} { identifier() "(" (ident_list())? ")" body() } void ident_list() : {} { identifier() ("," identifier())* } void identifier() : {} { | | } //--------------------------- FUNCTION CALLS AND RETURNS ---------------------------------- // parameter and return values can be numbers, sets, or booleans void fn_call() : {} { "(" (value_list())? ")" | "(" (value_list())? ")" } void boolean_call() : {} { "(" (value_list())? ")" } void value_list() : {} { value() ("," value())* } void return_stat() : {} { value() } void value() : {} { LOOKAHEAD(condition()) condition() | expression() } //--------------------------- MISCELLANEOUS STATEMENTS ---------------------------------- void assign_stat() : {} { "=" expression() | "=" expression() | "=" condition() } void print_stat() : {} { print_list() } void println_stat() : {} { (print_list())? } void print_list() : {} { (value() | ) ("," (value() | ))* } //--------------------------- IF AND LOOP STATEMENTS ---------------------------------- void if_stat() : {} { condition() clause() elifs() ( clause())? } void elifs() : {} { ( condition() clause())* } void for_stat() : {} { exp_list() body() } void while_stat() : {} { condition() body() } //--------------------------- CONDITIONS --------------------------------------------------- // Conditions will evaluate to Boolean value True or False void condition() : {} { and_clause() ("|" and_clause())* } void and_clause() : {} { not_clause() ("&" not_clause())* } void not_clause() : {} { "!" not_clause() | LOOKAHEAD(expression() comparator()) comparison() | "(" condition() ")" | LOOKAHEAD(2) boolean_call() | | | } void comparison() : {} { expression() comparator() expression() } void comparator() : {} { "<" | "<=" | ">" | ">=" | "==" | "!=" | | } //--------------------------- EXPRESSIONS ------------------------------------------------ // Expressions will evaluate to sets or numbers void exp_list() : {} { expression() ("," expression())* } void expression() : {} { ("+" | "-")? product() (("+"| "-") product())* } void product() : {} { term() (("*"| "/" | "%") term())* } void term() : {} { "(" expression() ")" | "|" expression() "|" | LOOKAHEAD(2) fn_call() | simple_term() } void simple_term() : {} { | | | interval() | "{" set() "}" } void interval() : {} { "[" expression() "," expression() "]" } void set() : {} { LOOKAHEAD(2) set_former() | (exp_list())? // set_const } void set_former() : {} { ( expression())? "|" condition() }