I have gone through the forums but I haven't found something similar. I have a file in this format.
(
: (yellow_domain
:gp_granularity_config_time ()
:gp_time (
:Time()
)
:lsm (false)
:type (pv1_customer)
)
: (blue_domain
:gp_granularity_config_time ()
:gp_time (
:Time()
)
:lsm (false)
:type (pv1_customer)
)
: (red_domain
:gp_granularity_config_time ()
:gp_time (
:Time()
)
:lsm (false)
:type (pv1_customer)
)
: (green_domain
:gp_granularity_config_time ()
:gp_time (
:Time()
)
:lsm (false)
:sofaware (false)
:type (pv1_customer)
)
)
I use the following command to delete the bracket starting with blue,
sed '/: (blue/,/:type (pv1_customer)/ {d;p}'
But it leaves the trailing parenthesis just a line before red bracket begins. If I use,
sed '/: (blue/,/:type (pv1_customer)/ {N;d;p}'
It works except the it also removes the red bracket. How can I make it so as to remove only one bracket and clean? Thanks.
Answer for original question
As I understand it, you want to delete from the blue to the following line that begins with ). This does that:
$ sed '/: (blue/,/^[[:space:]]*)/d' input
(
: (yellow_domain
:gp_granularity_config_time ()
:gp_time ()
:lsm (false)
:type (pv1_customer)
)
: (red_domain
:gp_granularity_config_time ()
:gp_time ()
:lsm (false)
:type (pv1_customer)
)
: (green_domain
:gp_granularity_config_time ()
:gp_time ()
:lsm (false)
:sofaware (false)
:type (pv1_customer)
)
)
/: (blue/ matches the start of the range. /^[[:space:]]*)/ matches the end of the range (marked by a line that begins with optional spaces followed by )). d tells sed to delete the range.
Answer for revised question
In the revised question, there are lines starting with the spaces-close parens pattern that do not end our group. In that case:
$ sed '/:type (pv1_customer)/N; /: (blue/,/:type (pv1_customer)/d' input
(
: (yellow_domain
:gp_granularity_config_time ()
:gp_time ()
:lsm (false)
:type (pv1_customer)
)
: (red_domain
:gp_granularity_config_time ()
:gp_time ()
:lsm (false)
:type (pv1_customer)
)
: (green_domain
:gp_granularity_config_time ()
:gp_time ()
:lsm (false)
:sofaware (false)
:type (pv1_customer)
)
)
This answer is more like your original approach but has some key changes:
/:type (pv1_customer)/N
Whenever we find a line that matches :type (pv1_customer), we read in the next line and add it to the pattern space.
/: (blue/,/:type (pv1_customer)/d
We delete all lines in groups starting with lines that match : (blue and ending with lines that match type (pv1_customer). But, note that since we have already read in the line after the line containing type (pv1_customer), it gets deleted at the same time.
How about '/: (blue/,/^ *)$/ d'?
This might work for you (GNU sed):
sed '/: (/h;G;/\n.*blue_domain/!P;d' file
This deletes all lines in the blue_domain block, it uses the hold space as a variable which is set on encountering the start of a block i.e. any line containing the string : (. Every line has the variable appended to it and only those lines without the blue_domain block in the variable are printed.
Related
The code starts with # as seen :
####################
# STORAGE VARIABLES
####################
#storage_var
func counter() -> (count : felt):
end
I run : starknet-compile ../counter.cairo --output counter_compiled.json --abi counter_abi.json
and the result is:
counter.cairo:7:1: Unexpected character "#"
Why this problem arises ? Is it about the cairo version ?
I am trying to create a class with string trimming functions:
Object subclass: Trimmer [
trimleading: str [ |ch ret|
ch := (str first: 1). "get first character"
ret := str. "make a copy of sent string"
[ch = ' '] whileTrue: [ "while first char is space"
ret := (ret copyFrom: 2). "copy from 2nd char"
ch := ret first: 1. "again test first char"
].
^ret "return value is modified string"
].
trim: str [ |ret|
ret := str.
ret := (trimleading value: ret). "trim leading spaces"
ret := (trimleading value: (ret reverse)). "reverse string and repeat trim leading"
^(ret reverse) "return reverse string"
]
].
oristr := ' this is a test '
('ORI..>>',oristr,'<<') displayNl.
('FINAL>>',((Trimmer new) trim: oristr),'<<') displayNl.
However, it is not running and giving following error:
$ gst trimstring_class.st
trimstring_class.st:10: invalid class body element
trimstring_class.st:17: expected expression
Where is the problem and how can this be solved?
If I remove the . after trimleading method block, as in following code:
Object subclass: Trimmer [
trimleading: str [ |ch ret flag|
ret := str. "make a copy of sent string"
flag := true.
[flag] whileTrue: [ "while first char is space"
ch := ret first: 1. "again test first char"
ch = ' '
ifTrue: [ ret := (ret copyFrom: 2 to: ret size)] "copy from 2nd char"
ifFalse: [flag := false]
].
^ret "value is modified string"
] "<<<<<<< PERIOD/DOT REMOVED FROM HERE."
trim: str [ |ret|
ret := str.
ret := (trimleading value: ret). "trim leading spaces"
ret := (trimleading value: (ret reverse)). "reverse string and repeat trim leading"
^(ret reverse) "return reverse string"
]
].
Then the code starts to run but stops with following error:
$ gst trimstring_class.st
trimstring_class.st:15: undefined variable trimleading referenced
ORI..>> this is a test <<
Object: Trimmer new "<0x7f1c787b4750>" error: did not understand #trim:
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
Trimmer(Object)>>doesNotUnderstand: #trim: (SysExcept.st:1448)
UndefinedObject>>executeStatements (trimstring_class.st:23)
Why trimleading method is undefined now and why gnu-smalltalk did not understand #trim:?
Usually it is wise for a such common use case to check if such functionallity was already implemented. You can take an inspiration from it for your code (you will improve as Smalltalk programmer too). Take a look at trimBlanksFrom: from sports.st:
SpStringUtilities class >> trimBlanksFrom: aString [
"^a String
I return a copy of aString with all leading and trailing blanks removed."
<category: 'services'>
| first last |
first := 1.
last := aString size.
[last > 0 and: [(aString at: last) isSeparator]]
whileTrue: [last := last - 1].
^last == 0
ifTrue: [String new]
ifFalse: [
[first < last and: [(aString at: first) isSeparator]]
whileTrue: [first := first + 1].
aString copyFrom: first to: last
]
]
If you want to trim only leading spaces you can just take the second part, where it is trimming the leading spaces.
EDIT The OP own code a fixes applied:
Object subclass: Trimmer [
trimleading: str [ |ch ret flag|
ret := str. "make a copy of sent string"
flag := true.
[flag] whileTrue: [ "while first char is space"
ch := ret first: 1. "again test first char"
ch = ' '
ifTrue: [ ret := (ret copyFrom: 2 to: ret size) ] "copy from 2nd char"
ifFalse: [flag := false ]
].
^ret "value is modified string"
] "<<<<<<< PERIOD/DOT REMOVED FROM HERE."
trim: str [ |ret|
ret := str.
ret := self trimleading: (ret copy). "trim leading spaces"
ret := self trimleading: (ret copy reverse). "reverse string and repeat trim leading"
^ (ret reverse) "return reverse string"
]
].
oristr := ' this is a test '
('ORI..>>',oristr,'<<') displayNl.
('FINAL>>',((Trimmer new) trim: oristr),'<<') displayNl.
The were some mistakes that needed to be fixed. If you want to address a selector #trimleading: you have to use self keyword which searches the local class (for own classes or inherited). Next you should not change a variable that you are assigning to you should use a #copy otherwise strange result can be expected.
I wanted a convenience function to catenate jQuery parent > child selector strings. I can't get the following to work in CS 1.10.0 (also tested in 1.7.1). What am I doing wrong?
pcsel = (parent_sel, child_sels...) ->
### Uitlity for forming parent > child selector string ###
childchain = [" > " + child for child in child_sels]
parent_sel + childchain.join('')
console.log pcsel("foo", "bar") # OK. yields "foo > bar"
console.log pcsel("foo", "bar", "glop") # BAD. yields "foo > bar, > glop"
# Sanity check
console.log "foo" + [" > bat", " > glop"].join('') # OK. yields "foo > bar > glop"
Thanks!
(I've also posted this as an issue in the CS repository)
A loop comprehension:
expr for e in array
evaluates to an array. That means that this:
[ expr for e in array ]
is actually a single element array whose first (and only) element is the array from the loop. More explicitly:
i for i in [1,2,3]
is [1,2,3] but this:
[ i for i in [1,2,3] ]
is [[1,2,3]].
Your problem is that childchain in pcsel ends up with an extra level of nesting and the stringification from the join call adds unexpected commas.
The solution is to fix pcsel:
childchain = (" > " + child for child in child_sels)
# -----------^-------------------------------------^
You need the parentheses (not brackets) to get around precedence issues; parentheses (()) and brackets ([]) serve entirely different functions so you need to use the right ones.
From what I can tell, the behavior you're seeing is what's to be expected. Here's how your code behaves if you replace the splat with an explicit array:
coffee> ["> " + ['bar']] # => ['> bar']
coffee> ["> " + ['bar', 'baz']] # =>['> bar,baz']
You'll also see the same behavior in node:
> [">" + ['bar']] // => ['>bar']
> ["> " + ['bar', 'baz']] // => ['> bar,baz']
You could achieve what you're after using multiple calls to .join, or by doing something like this:
pcsel = (parent_sel, child_sels...) ->
child_sels.reduce (memo, sel) ->
memo + " > #{sel}"
, parent_sel
console.log pcsel("foo", "bar") # => foo > bar
console.log pcsel("foo", "bar", "glop") # => foo > bar > glop
console.log pcsel("foo", "bar", "glop", "baz") # => foo > bar > glop > baz
This looked easy but it's messing with my head.
Convert this
"value:::text:::::othervalue:::::::text"
to this
"value: : :text: : : : :othervalue: : : : : : :text"
SED isn't recursive, so I get this:
$ echo "value:::text:::::othervalue:::::::text" | sed 's/::/: :/g'
> value: ::text: :: ::othervalue: :: :: ::text
Workaround, sed twice
$ echo "value:::text:::::othervalue:::::::text" | sed 's/::/: :/g;s/::/: :/g'
> value: : :text: : : : :othervalue: : : : : : :text
This doesn't look elegant, and it's not intuitive. Is there any command (in sed maybe?) that might do this more cleanly?
Thanks!
Note: I'm looking for readability.
With GNU sed:
echo '"value:::text:::::othervalue:::::::text"' | sed ':a;s/::/: :/g;ta'
Output:
"value: : :text: : : : :othervalue: : : : : : :text"
From sed man page:
t label: If a s/// has done a successful substitution since the last input line was read and since the last t or T command, then branch to label; if label is omitted, branch to end of script.
: label: Label for b and t commands.
sorry for my english! I have problem, faced here with such a problem, give the decision:
line 1:0 required (...)+ loop did not match anything at input < E O F
>
This my file, calc.g
grammar calc;
options {
language = Java;
}
rule: statement+;
statement
: expr NEWLINE
| ID '=' expr NEWLINE
| NEWLINE
;
NEWLINE : '\r'? '\n'
;
expr
: multExpression ('+' multExpression |'-' multExpression)*
;
multExpression
: a1=atom ('*' a2=atom | '/' a2=atom)*
;
atom
: ID
| INT
| '(' expr ')'
;
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
INT : ('1'..'9') ('0'..'9')*
;
this is my main:
ANTLRReaderStream input = new ANTLRReaderStream();
calcLexer lexer = new calcLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
calcParser parser = new calcParser(tokens);
parser.rule();
It looks like your input is empty: the parser immediately encounters the EOF (end-of-file) where it expects at least one statement.
Try something like this:
ANTLRStringStream input = new ANTLRStringStream("2*42\n");
calcLexer lexer = new calcLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
calcParser parser = new calcParser(tokens);
parser.rule();
As 280Z28 mentioned in the comment beneath my answer, you should probably force the parser to consume the entire input by adding EOF at the end of your parser's entry point:
rule: statement+ EOF;
and if you want to allow an empty string to be valid input too, change the + to a *;
rule: statement* EOF;
I didn't test it but think you have to add the default EOF token to your grammar:
rule: statement+ EOF!;
Your parser seems to recognize the whole input but at the end there is an EOF but you did not add the corresponding rule to your grammar.