diff --git a/src/grammar/Liquid.g b/src/grammar/Liquid.g deleted file mode 100644 index eab25291..00000000 --- a/src/grammar/Liquid.g +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (c) 2010 by Bart Kiers - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Project : Liqp; a Liquid Template grammar/parser - * Developed by : Bart Kiers, bart@big-o.nl - */ -grammar Liquid; - -options { - output=AST; - ASTLabelType=CommonTree; -} - -tokens { - ASSIGNMENT; - ATTRIBUTES; - BLOCK; - CAPTURE; - CASE; - COMMENT; - CYCLE; - ELSE; - FILTERS; - FILTER; - FOR_ARRAY; - FOR_BLOCK; - FOR_RANGE; - GROUP; - HASH; - IF; - INDEX; - ELSIF; - INCLUDE; - LOOKUP; - OUTPUT; - PARAMS; - PLAIN; - RAW; - TABLE; - UNLESS; - WHEN; - WITH; - NO_SPACE; - CUSTOM_TAG; - CUSTOM_TAG_BLOCK; -} - -@parser::header { - package liqp.parser; -} - -@lexer::header { - package liqp.parser; -} - -@parser::members { - @Override - public void reportError(RecognitionException e) { - throw new RuntimeException(e); - } -} - -@lexer::members { - private boolean inTag = false; - private boolean inRaw = false; - - private boolean openRawEndTagAhead() { - - if(!openTagAhead()) { - return false; - } - - int indexLA = 3; - - while(Character.isSpaceChar(input.LA(indexLA))) { - indexLA++; - } - - return input.LA(indexLA) == 'e' && - input.LA(indexLA + 1) == 'n' && - input.LA(indexLA + 2) == 'd' && - input.LA(indexLA + 3) == 'r' && - input.LA(indexLA + 4) == 'a' && - input.LA(indexLA + 5) == 'w'; - } - - private boolean openTagAhead() { - return input.LA(1) == '{' && (input.LA(2) == '{' || input.LA(2) == '\u0025'); - } - - @Override - public void reportError(RecognitionException e) { - throw new RuntimeException(e); - } - - private String strip(String text, boolean singleQuoted) { - return text.substring(1, text.length() - 1); - } -} - -/* parser rules */ -parse - : block EOF -> block - //(t=. {System.out.printf("\%-20s '\%s'\n", tokenNames[$t.type], $t.text);})* EOF - ; - -block - : (options{greedy=true;}: atom)* -> ^(BLOCK atom*) - ; - -atom - : tag - | output - | assignment - | Other -> PLAIN[$Other.text] - ; - -tag - : custom_tag - | raw_tag - | comment_tag - | if_tag - | unless_tag - | case_tag - | cycle_tag - | for_tag - | table_tag - | capture_tag - | include_tag - | break_tag - | continue_tag - ; - -custom_tag - : (TagStart Id (expr (Comma expr)*)? TagEnd -> ^(CUSTOM_TAG Id expr*)) - ((custom_tag_block)=> custom_tag_block -> ^(CUSTOM_TAG_BLOCK Id expr* custom_tag_block))? - ; - -custom_tag_block - : (options{greedy=false;}: atom)* TagStart EndId TagEnd -> ^(BLOCK atom*) - ; - -raw_tag - : TagStart RawStart TagEnd raw_body TagStart RawEnd TagEnd -> raw_body - ; - -raw_body - : other_than_tag_start -> RAW[$other_than_tag_start.text] - ; - -comment_tag - : TagStart CommentStart TagEnd comment_body TagStart CommentEnd TagEnd -> comment_body - ; - -comment_body - : other_than_tag_start -> COMMENT[$other_than_tag_start.text] - ; - -other_than_tag_start - : ~TagStart* - ; - -if_tag - : TagStart IfStart expr TagEnd block elsif_tag* else_tag? TagStart IfEnd TagEnd -> ^(IF expr block elsif_tag* ^(ELSE else_tag?)) - ; - -elsif_tag - : TagStart Elsif expr TagEnd block -> ^(ELSIF expr block) - ; - -else_tag - : TagStart Else TagEnd block -> block - ; - -unless_tag - : TagStart UnlessStart expr TagEnd block else_tag? TagStart UnlessEnd TagEnd -> ^(UNLESS expr block ^(ELSE else_tag?)) - ; - -case_tag - : TagStart CaseStart expr TagEnd Other? when_tag+ else_tag? TagStart CaseEnd TagEnd -> ^(CASE expr when_tag+ ^(ELSE else_tag?)) - ; - -when_tag - : TagStart When term ((Or | Comma) term)* TagEnd block -> ^(WHEN term+ block) - ; - -cycle_tag - : TagStart Cycle cycle_group expr (Comma expr)* TagEnd -> ^(CYCLE cycle_group expr+) - ; - -cycle_group - : ((expr Col)=> expr Col)? -> ^(GROUP expr?) - ; - -for_tag - : for_array - | for_range - ; - -for_array - : TagStart ForStart Id In lookup attribute* TagEnd - for_block - TagStart ForEnd TagEnd - -> ^(FOR_ARRAY Id lookup for_block ^(ATTRIBUTES attribute*)) - ; - -for_range - : TagStart ForStart Id In OPar expr DotDot expr CPar attribute* TagEnd - block - TagStart ForEnd TagEnd - -> ^(FOR_RANGE Id expr expr block ^(ATTRIBUTES attribute*)) - ; - -for_block - : a=block (TagStart Else TagEnd b=block)? -> ^(FOR_BLOCK block block?) - ; - -attribute - : Id Col expr -> ^(Id expr) - ; - -table_tag - : TagStart TableStart Id In lookup attribute* TagEnd block TagStart TableEnd TagEnd -> ^(TABLE Id lookup block ^(ATTRIBUTES attribute*)) - ; - -capture_tag - : TagStart CaptureStart ( Id TagEnd block TagStart CaptureEnd TagEnd -> ^(CAPTURE Id block) - | Str TagEnd block TagStart CaptureEnd TagEnd -> ^(CAPTURE Id[$Str.text] block) - ) - ; - -include_tag - : TagStart Include a=Str (With b=Str)? TagEnd -> ^(INCLUDE $a ^(WITH $b?)) - ; - -break_tag - : TagStart Break TagEnd -> Break - ; - -continue_tag - : TagStart Continue TagEnd -> Continue - ; - -output - : OutStart expr filter* OutEnd -> ^(OUTPUT expr ^(FILTERS filter*)) - ; - -filter - : Pipe Id params? -> ^(FILTER Id ^(PARAMS params?)) - ; - -params - : Col expr (Comma expr)* -> expr+ - ; - -assignment - : TagStart Assign Id EqSign expr filter? TagEnd -> ^(ASSIGNMENT Id filter? expr) - ; - -expr - : or_expr - ; - -or_expr - : and_expr (Or^ and_expr)* - ; - -and_expr - : contains_expr (And^ contains_expr)* - ; - -contains_expr - : eq_expr (Contains^ eq_expr)? - ; - -eq_expr - : rel_expr ((Eq | NEq)^ rel_expr)* - ; - -rel_expr - : term ((LtEq | Lt | GtEq | Gt)^ term)? - ; - -term - : DoubleNum - | LongNum - | Str - | True - | False - | Nil - | NoSpace+ -> NO_SPACE[$text] - | lookup - | Empty - | OPar expr CPar -> expr - ; - -lookup - : id index* QMark? -> ^(LOOKUP id index* QMark?) - | OBr Str CBr QMark? -> ^(LOOKUP Id[$Str.text] QMark?) - | OBr Id CBr QMark? -> ^(LOOKUP Id["@" + $Id.text] QMark?) - ; - -id - : Id - | Continue -> Id[$Continue.text] - ; - -id2 - : id - | Empty -> Id[$Empty.text] - ; - -index - : Dot id2 -> ^(HASH id2) - | OBr expr CBr -> ^(INDEX expr) - ; - -/* lexer rules */ -OutStart : '{{' {inTag=true;}; -OutEnd : '}}' {inTag=false;}; -TagStart : '{%' {inTag=true;}; -TagEnd : '%}' {inTag=false;}; - -Str : {inTag}?=> (SStr | DStr); - -DotDot : {inTag}?=> '..'; -Dot : {inTag}?=> '.'; -NEq : {inTag}?=> '!=' | '<>'; -Eq : {inTag}?=> '=='; -EqSign : {inTag}?=> '='; -GtEq : {inTag}?=> '>='; -Gt : {inTag}?=> '>'; -LtEq : {inTag}?=> '<='; -Lt : {inTag}?=> '<'; -Minus : {inTag}?=> '-'; -Pipe : {inTag}?=> '|'; -Col : {inTag}?=> ':'; -Comma : {inTag}?=> ','; -OPar : {inTag}?=> '('; -CPar : {inTag}?=> ')'; -OBr : {inTag}?=> '['; -CBr : {inTag}?=> ']'; -QMark : {inTag}?=> '?'; - -DoubleNum : {inTag}?=> '-'? Digit+ ( {input.LA(1) == '.' && input.LA(2) != '.'}?=> '.' Digit* - | {$type = LongNum;} - ); -LongNum : {inTag}?=> '-'? Digit+; -WS : {inTag}?=> (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;}; - -Id - : {inTag}?=> (Letter | '_') (Letter | '_' | '-' | Digit)* - { - if($text.equals("capture")) $type = CaptureStart; - else if($text.equals("endcapture")) $type = CaptureEnd; - else if($text.equals("comment")) $type = CommentStart; - else if($text.equals("endcomment")) $type = CommentEnd; - else if($text.equals("raw")) { $type = RawStart; inRaw = true; } - else if($text.equals("endraw")) { $type = RawEnd; inRaw = false; } - else if($text.equals("if")) $type = IfStart; - else if($text.equals("elsif")) $type = Elsif; - else if($text.equals("endif")) $type = IfEnd; - else if($text.equals("unless")) $type = UnlessStart; - else if($text.equals("endunless")) $type = UnlessEnd; - else if($text.equals("else")) $type = Else; - else if($text.equals("contains")) $type = Contains; - else if($text.equals("case")) $type = CaseStart; - else if($text.equals("endcase")) $type = CaseEnd; - else if($text.equals("when")) $type = When; - else if($text.equals("cycle")) $type = Cycle; - else if($text.equals("for")) $type = ForStart; - else if($text.equals("endfor")) $type = ForEnd; - else if($text.equals("in")) $type = In; - else if($text.equals("and")) $type = And; - else if($text.equals("or")) $type = Or; - else if($text.equals("tablerow")) $type = TableStart; - else if($text.equals("endtablerow")) $type = TableEnd; - else if($text.equals("assign")) $type = Assign; - else if($text.equals("true")) $type = True; - else if($text.equals("false")) $type = False; - else if($text.equals("nil")) $type = Nil; - else if($text.equals("null")) $type = Nil; - else if($text.equals("include")) $type = Include; - else if($text.equals("with")) $type = With; - else if($text.startsWith("end")) $type = EndId; - else if($text.equals("break")) $type = Break; - else if($text.startsWith("continue")) $type = Continue; - else if($text.startsWith("empty")) $type = Empty; - } - ; - -Other - : ({!inTag && !openTagAhead()}?=> . )+ - | ({!inTag && inRaw && !openRawEndTagAhead()}?=> . )+ - ; - -NoSpace - : ~(' ' | '\t' | '\r' | '\n') - ; - -/* fragment rules */ -fragment Letter : 'a'..'z' | 'A'..'Z'; -fragment Digit : '0'..'9'; -fragment SStr : '\'' ~'\''* '\'' {setText(strip($text, true));}; -fragment DStr : '"' ~'"'* '"' {setText(strip($text, false));}; - -fragment CommentStart : 'CommentStart'; -fragment CommentEnd : 'CommentEnd'; -fragment RawStart : 'RawStart'; -fragment RawEnd : 'RawEnd'; -fragment IfStart : 'IfStart'; -fragment IfEnd : 'IfEnd'; -fragment Elsif : 'Elsif'; -fragment UnlessStart : 'UnlessStart'; -fragment UnlessEnd : 'UnlessEnd'; -fragment Else : 'Else'; -fragment Contains : 'contains'; -fragment CaseStart : 'CaseStart'; -fragment CaseEnd : 'CaseEnd'; -fragment When : 'When'; -fragment Cycle : 'Cycle'; -fragment ForStart : 'ForStart'; -fragment ForEnd : 'ForEnd'; -fragment In : 'In'; -fragment And : 'And'; -fragment Or : 'Or'; -fragment TableStart : 'TableStart'; -fragment TableEnd : 'TableEnd'; -fragment Assign : 'Assign'; -fragment True : 'True'; -fragment False : 'False'; -fragment Nil : 'Nil'; -fragment Include : 'Include'; -fragment With : 'With'; -fragment CaptureStart : 'CaptureStart'; -fragment CaptureEnd : 'CaptureEnd'; -fragment EndId : 'EndId'; -fragment Break : 'Break'; -fragment Continue : 'Continue'; -fragment Empty : 'Empty'; diff --git a/src/grammar/LiquidWalker.g b/src/grammar/LiquidWalker.g deleted file mode 100644 index dd50a202..00000000 --- a/src/grammar/LiquidWalker.g +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2010 by Bart Kiers - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Project : Liqp; a Liquid Template grammar/parser - * Developed by : Bart Kiers, bart@big-o.nl - */ -tree grammar LiquidWalker; - -options { - tokenVocab=Liquid; - ASTLabelType=CommonTree; -} - -@header { - package liqp.nodes; - - import liqp.parser.*; - import liqp.tags.*; -} - -@members { - // ... -} - -walk returns [LNode node] - : block {$node = $block.node;} - ; - -block returns [BlockNode node] -@init{$node = new BlockNode();} - : ^(BLOCK (atom {$node.add($atom.node);})*) - ; - -atom returns [LNode node] - : tag {$node = $tag.node;} - | output {$node = $output.node;} - | assignment {$node = $assignment.node;} - | PLAIN {$node = new AtomNode($PLAIN.text);} - ; - -tag returns [LNode node] - : raw_tag {$node = $raw_tag.node;} - | comment_tag {$node = $comment_tag.node;} - | if_tag {$node = $if_tag.node;} - | unless_tag {$node = $unless_tag.node;} - | case_tag {$node = $case_tag.node;} - | cycle_tag {$node = $cycle_tag.node;} - | for_tag {$node = $for_tag.node;} - | table_tag {$node = $table_tag.node;} - | capture_tag {$node = $capture_tag.node;} - | include_tag {$node = $include_tag.node;} - | custom_tag {$node = $custom_tag.node;} - | custom_tag_block {$node = $custom_tag_block.node;} - | break_tag {$node = $break_tag.node;} - | continue_tag {$node = $continue_tag.node;} - ; - -raw_tag returns [LNode node] - : RAW {$node = new TagNode("raw", new AtomNode($RAW.text));} - ; - -comment_tag returns [LNode node] - : COMMENT {$node = new TagNode("comment", new AtomNode($COMMENT.text));} - ; - -if_tag returns [LNode node] -@init{List nodes = new ArrayList();} - : ^(IF e1=expr b1=block {nodes.add($e1.node); nodes.add($b1.node);} - (^(ELSIF e2=expr b2=block {nodes.add($e2.node); nodes.add($b2.node);} ))* - ^(ELSE (b3=block {nodes.add(new AtomNode("TRUE")); nodes.add($b3.node);} )?) - ) - {$node = new TagNode("if", nodes.toArray(new LNode[nodes.size()]));} - ; - -unless_tag returns [LNode node] -@init{List nodes = new ArrayList();} - : ^(UNLESS expr b1=block {nodes.add($expr.node); nodes.add($b1.node);} - ^(ELSE (b2=block {nodes.add(new AtomNode(null)); nodes.add($b2.node);})?)) - {$node = new TagNode("unless", nodes.toArray(new LNode[nodes.size()]));} - ; - -case_tag returns [LNode node] -@init{List nodes = new ArrayList();} - : ^(CASE expr {nodes.add($expr.node);} - (when_tag [nodes] )+ - ^(ELSE (block {nodes.add(nodes.get(0)); nodes.add($block.node);} )?)) - {$node = new TagNode("case", nodes.toArray(new LNode[nodes.size()]));} - ; - -when_tag[List nodes] - : ^(WHEN (expr {nodes.add($expr.node);})+ block) {nodes.add($block.node);} - ; - -cycle_tag returns [LNode node] -@init{List nodes = new ArrayList();} - : ^(CYCLE cycle_group {nodes.add($cycle_group.node);} (e=expr {nodes.add($e.node);})+) - {$node = new TagNode("cycle", nodes.toArray(new LNode[nodes.size()]));} - ; - -cycle_group returns [LNode node] - : ^(GROUP expr?) {$node = $expr.node;} - ; - -for_tag returns [LNode node] - : for_array {$node = $for_array.node;} - | for_range {$node = $for_range.node;} - ; - -for_array returns [LNode node] -@init{ - List expressions = new ArrayList(); - expressions.add(new AtomNode(true)); -} - : ^(FOR_ARRAY Id lookup {expressions.add(new AtomNode($Id.text)); expressions.add($lookup.node);} - for_block {expressions.add($for_block.node1); expressions.add($for_block.node2);} - ^(ATTRIBUTES (attribute {expressions.add($attribute.node);})*) - ) - {$node = new TagNode("for", expressions.toArray(new LNode[expressions.size()]));} - ; - -for_range returns [LNode node] -@init{ - List expressions = new ArrayList(); - expressions.add(new AtomNode(false)); -} - : ^(FOR_RANGE Id from=expr to=expr {expressions.add(new AtomNode($Id.text)); expressions.add($from.node); expressions.add($to.node);} - block {expressions.add($block.node);} - ^(ATTRIBUTES (attribute {expressions.add($attribute.node);})*) - ) - {$node = new TagNode("for", expressions.toArray(new LNode[expressions.size()]));} - ; - -for_block returns [LNode node1, LNode node2] - : ^(FOR_BLOCK n1=block n2=block?) - { - $node1 = $n1.node; - $node2 = $n2.node; - } - ; - -attribute returns [LNode node] - : ^(Id expr) {$node = new AttributeNode(new AtomNode($Id.text), $expr.node);} - ; - -table_tag returns [LNode node] -@init{ - List expressions = new ArrayList(); -} - : ^(TABLE - Id {expressions.add(new AtomNode($Id.text));} - lookup {expressions.add($lookup.node);} - block {expressions.add($block.node);} - ^(ATTRIBUTES (attribute {expressions.add($attribute.node);})*) - ) - {$node = new TagNode("tablerow", expressions.toArray(new LNode[expressions.size()]));} - ; - -capture_tag returns [LNode node] - : ^(CAPTURE Id block) {$node = new TagNode("capture", new AtomNode($Id.text), $block.node);} - ; - -include_tag returns [LNode node] - : ^(INCLUDE file=Str ^(WITH (with=Str)?)) - { - if($with.text != null) { - $node = new TagNode("include", new AtomNode($file.text), new AtomNode($with.text)); - } else { - $node = new TagNode("include", new AtomNode($file.text)); - } - } - ; - -break_tag returns [LNode node] - : Break {$node = new AtomNode(Tag.Statement.BREAK);} - ; - -continue_tag returns [LNode node] - : Continue {$node = new AtomNode(Tag.Statement.CONTINUE);} - ; - - -custom_tag returns [LNode node] -@init{List expressions = new ArrayList();} - : ^(CUSTOM_TAG Id (expr {expressions.add($expr.node);})*) - {$node = new TagNode($Id.text, expressions.toArray(new LNode[expressions.size()]));} - ; - -custom_tag_block returns [LNode node] -@init{List expressions = new ArrayList();} - : ^(CUSTOM_TAG_BLOCK Id (expr {expressions.add($expr.node);})* block {expressions.add($block.node);}) - {$node = new TagNode($Id.text, expressions.toArray(new LNode[expressions.size()]));} - ; - -output returns [OutputNode node] - : ^(OUTPUT expr {$node = new OutputNode($expr.node);} ^(FILTERS (filter {$node.addFilter($filter.node);})*)) - ; - -filter returns [FilterNode node] - : ^(FILTER Id {$node = new FilterNode($Id.text);} ^(PARAMS params[$node]?)) - ; - -params[FilterNode node] - : (expr {$node.add($expr.node);})+ - ; - -assignment returns [TagNode node] - : ^(ASSIGNMENT Id filter? expr) {$node = new TagNode("assign", new AtomNode($Id.text), $filter.node, $expr.node);} - ; - -expr returns [LNode node] - : ^(Or a=expr b=expr) {$node = new OrNode($a.node, $b.node);} - | ^(And a=expr b=expr) {$node = new AndNode($a.node, $b.node);} - | ^(Eq a=expr b=expr) {$node = new EqNode($a.node, $b.node);} - | ^(NEq a=expr b=expr) {$node = new NEqNode($a.node, $b.node);} - | ^(LtEq a=expr b=expr) {$node = new LtEqNode($a.node, $b.node);} - | ^(Lt a=expr b=expr) {$node = new LtNode($a.node, $b.node);} - | ^(GtEq a=expr b=expr) {$node = new GtEqNode($a.node, $b.node);} - | ^(Gt a=expr b=expr) {$node = new GtNode($a.node, $b.node);} - | ^(Contains a=expr b=expr) {$node = new ContainsNode($a.node, $b.node);} - | LongNum {$node = new AtomNode(new Long($LongNum.text));} - | DoubleNum {$node = new AtomNode(new Double($DoubleNum.text));} - | Str {$node = new AtomNode($Str.text);} - | True {$node = new AtomNode(true);} - | False {$node = new AtomNode(false);} - | Nil {$node = new AtomNode(null);} - | NO_SPACE {$node = new AtomNode($NO_SPACE.text);} - | lookup {$node = $lookup.node;} - | Empty {$node = AtomNode.EMPTY;} - ; - -lookup returns [LookupNode node] - : ^(LOOKUP - Id {$node = new LookupNode($Id.text);} - ( index {$node.add($index.indexable);} - )* - QMark? - ) - ; - -index returns [LookupNode.Indexable indexable] - : ^(HASH Id) {$indexable = new LookupNode.Hash($Id.text);} - | ^(INDEX expr) {$indexable = new LookupNode.Index($expr.node);} - ;